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 --- 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 + 245 files changed, 64919 insertions(+) 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 (limited to 'catalog-model') diff --git a/catalog-model/.gitignore b/catalog-model/.gitignore new file mode 100644 index 0000000000..d9d66d8144 --- /dev/null +++ b/catalog-model/.gitignore @@ -0,0 +1,2 @@ +/target +/bin/ diff --git a/catalog-model/pom.xml b/catalog-model/pom.xml new file mode 100644 index 0000000000..32116b2370 --- /dev/null +++ b/catalog-model/pom.xml @@ -0,0 +1,267 @@ + + + 4.0.0 + + org.openecomp.sdc.be + catalog-model + + + + org.openecomp.sdc + sdc-main + 1.0.0-SNAPSHOT + + + + + + + + + org.openecomp.sdc + common-app-api + ${common-app-api.version} + provided + + + org.openecomp.sdc.be + common-be + ${common-be.version} + provided + + + + ch.qos.logback + logback-classic + provided + + + + ch.qos.logback + logback-core + provided + + + + + org.openecomp.sdc.be + catalog-dao + ${catalog-dao.version} + provided + + + + + com.google.guava + guava + ${guava.version} + provided + + + + org.functionaljava + functionaljava + provided + + + + javax.servlet + servlet-api + provided + + + + + org.springframework + spring-beans + provided + + + + org.springframework + spring-context + provided + + + + javax.validation + validation-api + 1.1.0.Final + + + + org.hibernate + hibernate-validator + 5.3.4.Final + + + + + com.google.code.gson + gson + provided + + + + + com.thinkaurelius.titan + titan-core + ${titan.version} + provided + + + org.json + json + + + slf4j-log4j12 + org.slf4j + + + + + + com.thinkaurelius.titan + titan-cassandra + ${titan.version} + provided + + + slf4j-log4j12 + org.slf4j + + + + + + + org.apache.commons + commons-lang3 + provided + + + + + org.apache.httpcomponents + httpclient + provided + + + + org.apache.httpcomponents + httpcore + provided + + + + + com.datastax.cassandra + cassandra-driver-core + ${cassandra.driver.version} + provided + + + com.datastax.cassandra + cassandra-driver-mapping + ${cassandra.driver.version} + provided + + + + + + + + + + junit + junit + test + + + + org.mockito + mockito-all + test + + + + org.springframework + spring-test + test + + + + org.aspectj + aspectjrt + 1.7.4 + test + + + + org.aspectj + aspectjweaver + 1.7.4 + test + + + + org.springframework + spring-web + test + + + + org.springframework + spring-tx + test + 4.0.7.RELEASE + + + + org.apache.commons + commons-jci-core + test + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + true + + + + + + + Fortify + + false + + + + + + com.fortify.ps.maven.plugin + sca-maven-plugin + 4.30 + + 1.8 + ${project.parent.artifactId} + ${project.parent.artifactId} + + + + + + + diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInfoParameterInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInfoParameterInfo.java new file mode 100644 index 0000000000..674681081c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInfoParameterInfo.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.be.model; + +import java.io.Serializable; + +public class AdditionalInfoParameterInfo implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 2066876282722907709L; + + String uniqueId; + String key; + String value; + + public AdditionalInfoParameterInfo() { + super(); + } + + public AdditionalInfoParameterInfo(String key, String value) { + super(); + this.key = key; + this.value = value; + } + + public AdditionalInfoParameterInfo(String uniqueId, String key, String value) { + super(); + this.uniqueId = uniqueId; + this.key = key; + this.value = value; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return "AdditionalInfoParameterInfo [uniqueId=" + uniqueId + ", key=" + key + ", value=" + value + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java new file mode 100644 index 0000000000..9ad0718e71 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.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.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition; + +public class AdditionalInformationDefinition extends AdditionalInfoParameterDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 5266684455492488001L; + + private String parentUniqueId; + + private List parameters; + + public AdditionalInformationDefinition() { + super(); + } + + public AdditionalInformationDefinition(AdditionalInfoParameterDataDefinition p, String parentUniqueId, + List parameters) { + super(p); + this.parentUniqueId = parentUniqueId; + this.parameters = parameters; + } + + public AdditionalInformationDefinition(AdditionalInformationDefinition pd) { + this.setUniqueId(pd.getUniqueId()); + this.setCreationTime(pd.getCreationTime()); + this.setModificationTime(pd.getModificationTime()); + this.parentUniqueId = pd.parentUniqueId; + this.parameters = pd.parameters; + } + + public String getParentUniqueId() { + return parentUniqueId; + } + + public void setParentUniqueId(String parentUniqueId) { + this.parentUniqueId = parentUniqueId; + } + + public List getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + + @Override + public String toString() { + return "AdditionalInformationDefinition [parameters=" + parameters + ", parentUniqueId=" + parentUniqueId + " " + + super.toString() + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java new file mode 100644 index 0000000000..f822e67715 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java @@ -0,0 +1,138 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; + +public class ArtifactDefinition extends ArtifactDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -8323923665449071631L; + + /** + * Base64 encoded Artifact file data + */ + private byte[] payloadData; + + private List heatParameters; + + private String generatedFromId; + + public byte[] getPayloadData() { + return payloadData; + } + + public void setPayload(byte[] payloadData) { + this.payloadData = payloadData; + } + + public void setPayloadData(String payloadData) { + if (payloadData != null) { + this.payloadData = payloadData.getBytes(); + } + } + + public ArtifactDefinition() { + super(); + } + + public ArtifactDefinition(ArtifactDataDefinition a) { + super(a); + + } + + public ArtifactDefinition(ArtifactDataDefinition a, String payloadData) { + super(a); + setPayloadData(payloadData); + } + + public List getHeatParameters() { + return heatParameters; + } + + public void setHeatParameters(List properties) { + this.heatParameters = properties; + } + + public String getGeneratedFromId() { + return generatedFromId; + } + + public void setGeneratedFromId(String generatedFromId) { + this.generatedFromId = generatedFromId; + } + + public boolean checkEsIdExist() { + if ((getEsId() != null) && (!getEsId().trim().isEmpty())) { + return true; + } + return false; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((generatedFromId == null) ? 0 : generatedFromId.hashCode()); + result = prime * result + ((heatParameters == null) ? 0 : heatParameters.hashCode()); + result = prime * result + ((payloadData == null) ? 0 : payloadData.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ArtifactDefinition other = (ArtifactDefinition) obj; + if (generatedFromId == null) { + if (other.generatedFromId != null) + return false; + } else if (!generatedFromId.equals(other.generatedFromId)) + return false; + if (heatParameters == null) { + if (other.heatParameters != null) + return false; + } else if (heatParameters.size() != other.heatParameters.size()) + return false; + else { + for (HeatParameterDefinition heatParam : heatParameters) { + if (!other.heatParameters.contains(heatParam)) { + return false; + } + } + } + if (payloadData == null) { + if (other.payloadData != null) + return false; + } else if (!payloadData.equals(other.payloadData)) + return false; + return true; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java new file mode 100644 index 0000000000..a761d74016 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.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.be.model; + +public class ArtifactType { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ArtifactType other = (ArtifactType) obj; + if (name == null) { + if (other.getClass() != null) { + return false; + } + } else if (!name.equals(other.getName())) { + return false; + } + return true; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java new file mode 100644 index 0000000000..7172ddc35d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.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.model; + +public class ArtifactUiDownloadData { + + // POJO for UI artifact download, holding artifact filename and base64 + // content + String artifactName; + String base64Contents; + + public void setArtifactName(String artifactName) { + this.artifactName = artifactName; + } + + public void setBase64Contents(String base64Contents) { + this.base64Contents = base64Contents; + } + + public String getArtifactName() { + return artifactName; + } + + public String getBase64Contents() { + return base64Contents; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java new file mode 100644 index 0000000000..120a87c610 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.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.model; + +import java.io.Serializable; + +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; + +public class AttributeDefinition extends AttributeDataDefinition implements IComplexDefaultValue, Serializable { + + /** + * + */ + private static final long serialVersionUID = -6306111879714097811L; + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((parentUniqueId == null) ? 0 : parentUniqueId.hashCode()); + return result; + } + + /** + * The resource id which this property belongs to + */ + private String parentUniqueId; + + public AttributeDefinition(AttributeDefinition hpdd) { + super(hpdd); + } + + public AttributeDefinition() { + super(); + } + + public AttributeDefinition(AttributeDataDefinition p) { + super(p); + } + + public String getParentUniqueId() { + return parentUniqueId; + } + + public void setParentUniqueId(String parentUniqueId) { + this.parentUniqueId = parentUniqueId; + } + + @Override + public String toString() { + return super.toString() + " [ parentUniqueId=" + parentUniqueId + "]"; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java new file mode 100644 index 0000000000..2f9cf48917 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.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.be.model; + +import java.util.List; +import java.util.Map; + +public class CapReqDef { + Map> capabilities; + Map> requirements; + + public CapReqDef() { + super(); + } + + public CapReqDef(Map> requirements, + Map> capabilities) { + super(); + this.capabilities = capabilities; + this.requirements = requirements; + } + + public Map> getCapabilities() { + return capabilities; + } + + public Map> getRequirements() { + return requirements; + } + + public void setCapabilities(Map> capabilities) { + this.capabilities = capabilities; + } + + public void setRequirements(Map> requirements) { + this.requirements = requirements; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java new file mode 100644 index 0000000000..61ba356aa1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java @@ -0,0 +1,266 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Specifies the capabilities that the Node Type exposes. + */ +public class CapabilityDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -3871825415338268030L; + + private String uniqueId; + + private String description; + + private String name; + + /** Identifies the type of the capability. */ + private String type; + + private List validSourceTypes; + + private List capabilitySources; + /** + * The properties field contains all properties defined for + * CapabilityDefinition + */ + private List properties; + + // specifies the resource instance holding this requirement + private String ownerId; + private String ownerName; + private String minOccurrences; + private String maxOccurrences; + + public CapabilityDefinition() { + super(); + } + + public CapabilityDefinition(CapabilityDefinition other) { + this.uniqueId = other.uniqueId; + this.description = other.description; + this.name = other.name; + this.type = other.type; + if (other.validSourceTypes != null) { + this.validSourceTypes = new ArrayList<>(other.validSourceTypes); + } + if (other.capabilitySources != null) { + this.capabilitySources = new ArrayList<>(other.capabilitySources); + } + if (other.properties != null) { + this.properties = new ArrayList<>(other.properties); + } + this.ownerId = other.ownerId; + this.ownerName = other.ownerName; + this.minOccurrences = other.minOccurrences; + this.maxOccurrences = other.maxOccurrences; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + 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 getValidSourceTypes() { + return validSourceTypes; + } + + public void setValidSourceTypes(List validSourceTypes) { + this.validSourceTypes = validSourceTypes; + } + + public List getCapabilitySources() { + return capabilitySources; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public void setCapabilitySources(List capabilitySources) { + this.capabilitySources = capabilitySources; + } + + public String getOwnerId() { + return ownerId; + } + + public void setOwnerId(String ownerId) { + this.ownerId = ownerId; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public String getMinOccurrences() { + return minOccurrences; + } + + public void setMinOccurrences(String minOccurrences) { + this.minOccurrences = minOccurrences; + } + + public String getMaxOccurrences() { + return maxOccurrences; + } + + public void setMaxOccurrences(String maxOccurrences) { + this.maxOccurrences = maxOccurrences; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((capabilitySources == null) ? 0 : capabilitySources.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((maxOccurrences == null) ? 0 : maxOccurrences.hashCode()); + result = prime * result + ((minOccurrences == null) ? 0 : minOccurrences.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode()); + result = prime * result + ((ownerName == null) ? 0 : ownerName.hashCode()); + result = prime * result + ((properties == null) ? 0 : properties.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode()); + result = prime * result + ((validSourceTypes == null) ? 0 : validSourceTypes.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CapabilityDefinition other = (CapabilityDefinition) obj; + if (capabilitySources == null) { + if (other.capabilitySources != null) + return false; + } else if (!capabilitySources.equals(other.capabilitySources)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (maxOccurrences == null) { + if (other.maxOccurrences != null) + return false; + } else if (!maxOccurrences.equals(other.maxOccurrences)) + return false; + if (minOccurrences == null) { + if (other.minOccurrences != null) + return false; + } else if (!minOccurrences.equals(other.minOccurrences)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (ownerId == null) { + if (other.ownerId != null) + return false; + } else if (!ownerId.equals(other.ownerId)) + return false; + if (ownerName == null) { + if (other.ownerName != null) + return false; + } else if (!ownerName.equals(other.ownerName)) + return false; + if (properties == null) { + if (other.properties != null) + return false; + } else if (!properties.equals(other.properties)) + return false; + if (type == null) { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + if (uniqueId == null) { + if (other.uniqueId != null) + return false; + } else if (!uniqueId.equals(other.uniqueId)) + return false; + if (validSourceTypes == null) { + if (other.validSourceTypes != null) + return false; + } else if (!validSourceTypes.equals(other.validSourceTypes)) + return false; + return true; + } + + @Override + public String toString() { + return "CapabilityDefinition [uniqueId=" + uniqueId + ", description=" + description + ", name=" + name + + ", type=" + type + ", validSourceTypes=" + validSourceTypes + ", capabilitySources=" + + capabilitySources + ", properties=" + properties + ", ownerId=" + ownerId + ", ownerName=" + ownerName + + ", minOccurrences=" + minOccurrences + ", maxOccurrences=" + maxOccurrences + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java new file mode 100644 index 0000000000..4291ee746d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.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.model; + +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.CapabilityTypeDataDefinition; + +/** + * Specifies the capabilities that the Node Type exposes. + */ +public class CapabilityTypeDefinition extends CapabilityTypeDataDefinition { + + private String derivedFrom; + + private Map properties; + + public String getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(String derivedFrom) { + this.derivedFrom = derivedFrom; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + public CapabilityTypeDefinition() { + super(); + } + + public CapabilityTypeDefinition(CapabilityTypeDataDefinition p) { + super(p); + } + + @Override + public String toString() { + return super.toString() + " [ derivedFrom=" + derivedFrom + ", properties=" + properties + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java new file mode 100644 index 0000000000..5e5edf99ac --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.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.model; + +import java.util.Map; + +public class CapabiltyInstance { + + private String uniqueId; + + private Map properties; + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + @Override + public String toString() { + return "CapabiltyInstance [uniqueId=" + uniqueId + ", properties=" + properties + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java new file mode 100644 index 0000000000..03cab66d53 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.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.model; + +public class Category { + + private String name;// will be changed to categoryDisplayName + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Category other = (Category) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "Category [name=" + name + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java new file mode 100644 index 0000000000..57a70de388 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java @@ -0,0 +1,598 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.codehaus.jackson.annotate.JsonIgnore; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; + +public abstract class Component implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -6373756459967949120L; + + private ComponentMetadataDefinition componentMetadataDefinition; + private Map artifacts; + private Map deploymentArtifacts; + private Map toscaArtifacts; + + private List categories; + + // User + private String creatorUserId; + private String creatorFullName; + private String lastUpdaterUserId; + private String lastUpdaterFullName; + + protected ComponentTypeEnum componentType; + + private List componentInstances; + + private List componentInstancesRelations; + + private Map> componentInstancesInputs; + + private Map> componentInstancesProperties; + + private Map> componentInstancesAttributes; + + private Map> capabilities; + + private Map> requirements; + + private List inputs; + + private List groups; + + public Component(ComponentMetadataDefinition componentMetadataDefinition) { + this.componentMetadataDefinition = componentMetadataDefinition; + } + + @JsonIgnore + public ComponentMetadataDefinition getComponentMetadataDefinition() { + return componentMetadataDefinition; + } + + public Map getArtifacts() { + return artifacts; + } + + public void setArtifacts(Map artifacts) { + this.artifacts = artifacts; + } + + public Map getToscaArtifacts() { + return toscaArtifacts; + } + + public void setToscaArtifacts(Map toscaArtifacts) { + this.toscaArtifacts = toscaArtifacts; + } + + public String getUniqueId() { + return componentMetadataDefinition.getMetadataDataDefinition().getUniqueId(); + } + + public void setUniqueId(String uniqueId) { + componentMetadataDefinition.getMetadataDataDefinition().setUniqueId(uniqueId); + } + + public void setName(String name) { + componentMetadataDefinition.getMetadataDataDefinition().setName(name); + } + + public void setVersion(String version) { + componentMetadataDefinition.getMetadataDataDefinition().setVersion(version); + } + + public void setHighestVersion(Boolean isHighestVersion) { + componentMetadataDefinition.getMetadataDataDefinition().setHighestVersion(isHighestVersion); + } + + public void setCreationDate(Long creationDate) { + componentMetadataDefinition.getMetadataDataDefinition().setCreationDate(creationDate); + } + + public void setLastUpdateDate(Long lastUpdateDate) { + componentMetadataDefinition.getMetadataDataDefinition().setLastUpdateDate(lastUpdateDate); + } + + public void setDescription(String description) { + componentMetadataDefinition.getMetadataDataDefinition().setDescription(description); + } + + public void setState(LifecycleStateEnum state) { + componentMetadataDefinition.getMetadataDataDefinition().setState(state.name()); + } + + public void setTags(List tags) { + componentMetadataDefinition.getMetadataDataDefinition().setTags(tags); + } + + public void setIcon(String icon) { + componentMetadataDefinition.getMetadataDataDefinition().setIcon(icon); + } + + public void setContactId(String contactId) { + componentMetadataDefinition.getMetadataDataDefinition().setContactId(contactId); + } + + 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 getName() { + return componentMetadataDefinition.getMetadataDataDefinition().getName(); + } + + public String getVersion() { + return componentMetadataDefinition.getMetadataDataDefinition().getVersion(); + } + + public Boolean isHighestVersion() { + return componentMetadataDefinition.getMetadataDataDefinition().isHighestVersion(); + } + + public Long getCreationDate() { + return componentMetadataDefinition.getMetadataDataDefinition().getCreationDate(); + } + + public Long getLastUpdateDate() { + return componentMetadataDefinition.getMetadataDataDefinition().getLastUpdateDate(); + } + + public String getDescription() { + return componentMetadataDefinition.getMetadataDataDefinition().getDescription(); + } + + public LifecycleStateEnum getLifecycleState() { + if (componentMetadataDefinition.getMetadataDataDefinition().getState() != null) { + return LifecycleStateEnum.valueOf(componentMetadataDefinition.getMetadataDataDefinition().getState()); + } else { + return null; + } + } + + public List getTags() { + return componentMetadataDefinition.getMetadataDataDefinition().getTags(); + } + + public String getIcon() { + return componentMetadataDefinition.getMetadataDataDefinition().getIcon(); + } + + public String getContactId() { + return componentMetadataDefinition.getMetadataDataDefinition().getContactId(); + } + + public List getInputs() { + return inputs; + } + + public void setInputs(List inputs) { + this.inputs = inputs; + } + + public void setLifecycleState(LifecycleStateEnum state) { + if (state != null) { + this.componentMetadataDefinition.getMetadataDataDefinition().setState(state.name()); + } + } + + public String getUUID() { + return componentMetadataDefinition.getMetadataDataDefinition().getUUID(); + } + + public void setUUID(String uUID) { + componentMetadataDefinition.getMetadataDataDefinition().setUUID(uUID); + } + + public void setSystemName(String systemName) { + componentMetadataDefinition.getMetadataDataDefinition().setSystemName(systemName); + } + + public String getSystemName() { + return componentMetadataDefinition.getMetadataDataDefinition().getSystemName(); + } + + public void setAllVersions(Map allVersions) { + componentMetadataDefinition.getMetadataDataDefinition().setAllVersions(allVersions); + } + + public Map getAllVersions() { + return componentMetadataDefinition.getMetadataDataDefinition().getAllVersions(); + } + + public Map getDeploymentArtifacts() { + return deploymentArtifacts; + } + + public void setDeploymentArtifacts(Map deploymentArtifacts) { + this.deploymentArtifacts = deploymentArtifacts; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public String getNormalizedName() { + return componentMetadataDefinition.getMetadataDataDefinition().getNormalizedName(); + } + + public void setNormalizedName(String normalizedName) { + componentMetadataDefinition.getMetadataDataDefinition().setNormalizedName(normalizedName); + } + + public ComponentTypeEnum getComponentType() { + return componentType; + } + + public void setComponentType(ComponentTypeEnum componentType) { + this.componentType = componentType; + } + + 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; + } + + public List getComponentInstances() { + return componentInstances; + } + + public void setComponentInstances(List resourceInstances) { + this.componentInstances = resourceInstances; + } + + public List getComponentInstancesRelations() { + return componentInstancesRelations; + } + + public void setComponentInstancesRelations(List resourceInstancesRelations) { + this.componentInstancesRelations = resourceInstancesRelations; + } + + public Map> getComponentInstancesProperties() { + return componentInstancesProperties; + } + + public void setComponentInstancesProperties( + Map> resourceInstancesProperties) { + this.componentInstancesProperties = resourceInstancesProperties; + } + + public Boolean getIsDeleted() { + return componentMetadataDefinition.getMetadataDataDefinition().isDeleted(); + } + + public void setIsDeleted(Boolean isDeleted) { + componentMetadataDefinition.getMetadataDataDefinition().setIsDeleted(isDeleted); + } + + public String getProjectCode() { + return componentMetadataDefinition.getMetadataDataDefinition().getProjectCode(); + } + + public void setProjectCode(String projectCode) { + componentMetadataDefinition.getMetadataDataDefinition().setProjectCode(projectCode); + } + + public String getCsarUUID() { + return componentMetadataDefinition.getMetadataDataDefinition().getCsarUUID(); + } + + public void setCsarUUID(String csarUUID) { + componentMetadataDefinition.getMetadataDataDefinition().setCsarUUID(csarUUID); + } + + public String getCsarVersion() { + return componentMetadataDefinition.getMetadataDataDefinition().getCsarVersion(); + } + + public void setCsarVersion(String csarVersion) { + componentMetadataDefinition.getMetadataDataDefinition().setCsarVersion(csarVersion); + } + + public String getImportedToscaChecksum() { + return componentMetadataDefinition.getMetadataDataDefinition().getImportedToscaChecksum(); + } + + public void setImportedToscaChecksum(String importedToscaChecksum) { + componentMetadataDefinition.getMetadataDataDefinition().setImportedToscaChecksum(importedToscaChecksum); + } + + public String getInvariantUUID() { + return componentMetadataDefinition.getMetadataDataDefinition().getInvariantUUID(); + } + + public void setInvariantUUID(String invariantUUID) { + componentMetadataDefinition.getMetadataDataDefinition().setInvariantUUID(invariantUUID); + } + + public List getGroups() { + return groups; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((artifacts == null) ? 0 : artifacts.hashCode()); + result = prime * result + ((categories == null) ? 0 : categories.hashCode()); + result = prime * result + ((componentMetadataDefinition == null) ? 0 : componentMetadataDefinition.hashCode()); + result = prime * result + ((creatorUserId == null) ? 0 : creatorUserId.hashCode()); + result = prime * result + ((creatorFullName == null) ? 0 : creatorFullName.hashCode()); + result = prime * result + ((deploymentArtifacts == null) ? 0 : deploymentArtifacts.hashCode()); + result = prime * result + ((lastUpdaterUserId == null) ? 0 : lastUpdaterUserId.hashCode()); + result = prime * result + ((lastUpdaterFullName == null) ? 0 : lastUpdaterFullName.hashCode()); + result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode()); + result = prime * result + ((requirements == null) ? 0 : requirements.hashCode()); + result = prime * result + ((componentInstances == null) ? 0 : componentInstances.hashCode()); + result = prime * result + + ((componentInstancesProperties == null) ? 0 : componentInstancesProperties.hashCode()); + result = prime * result + + ((componentInstancesAttributes == null) ? 0 : componentInstancesAttributes.hashCode()); + result = prime * result + ((componentInstancesInputs == null) ? 0 : componentInstancesInputs.hashCode()); + result = prime * result + ((componentInstancesRelations == null) ? 0 : componentInstancesRelations.hashCode()); + result = prime * result + ((groups == null) ? 0 : groups.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Component other = (Component) obj; + if (artifacts == null) { + if (other.artifacts != null) + return false; + } else if (!artifacts.equals(other.artifacts)) + return false; + if (categories == null) { + if (other.categories != null) + return false; + } else if (!categories.equals(other.categories)) + return false; + if (componentMetadataDefinition == null) { + if (other.componentMetadataDefinition != null) + return false; + } else if (!componentMetadataDefinition.equals(other.componentMetadataDefinition)) + return false; + if (creatorUserId == null) { + if (other.creatorUserId != null) + return false; + } else if (!creatorUserId.equals(other.creatorUserId)) + return false; + if (creatorFullName == null) { + if (other.creatorFullName != null) + return false; + } else if (!creatorFullName.equals(other.creatorFullName)) + return false; + if (deploymentArtifacts == null) { + if (other.deploymentArtifacts != null) + return false; + } else if (!deploymentArtifacts.equals(other.deploymentArtifacts)) + return false; + if (lastUpdaterUserId == null) { + if (other.lastUpdaterUserId != null) + return false; + } else if (!lastUpdaterUserId.equals(other.lastUpdaterUserId)) + return false; + if (lastUpdaterFullName == null) { + if (other.lastUpdaterFullName != null) + return false; + } else if (!lastUpdaterFullName.equals(other.lastUpdaterFullName)) + return false; + if (componentInstances == null) { + if (other.componentInstances != null) + return false; + } else if (!componentInstances.equals(other.componentInstances)) + return false; + if (componentInstancesProperties == null) { + if (other.componentInstancesProperties != null) + return false; + } else if (!componentInstancesProperties.equals(other.componentInstancesProperties)) + return false; + + if (!Objects.equals(componentInstancesAttributes, other.componentInstancesAttributes)) { + return false; + } + if (!Objects.equals(componentInstancesInputs, other.componentInstancesInputs)) { + return false; + } + if (componentInstancesRelations == null) { + if (other.componentInstancesRelations != null) + return false; + } else if (!componentInstancesRelations.equals(other.componentInstancesRelations)) + return false; + if (requirements == null) { + if (other.requirements != null) + return false; + } else if (!requirements.equals(other.requirements)) + return false; + if (capabilities == null) { + if (other.capabilities != null) + return false; + } else if (!capabilities.equals(other.capabilities)) + return false; + if (groups == null) { + if (other.groups != null) + return false; + } else if (!groups.equals(other.groups)) + return false; + return true; + } + + public void addCategory(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); + } + 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(CategoryDefinition category) { + addCategory(category, null); + } + + public void addCategory(CategoryDefinition category, SubCategoryDefinition subCategory) { + if (categories == null) { + categories = new ArrayList<>(); + } + boolean foundCat = false; + for (CategoryDefinition cat : categories) { + if (cat.getName().equals(category.getName())) { + foundCat = true; + if (subCategory != null) { + List subcategories = cat.getSubcategories(); + if (subcategories == null) { + subcategories = new ArrayList<>(); + cat.setSubcategories(subcategories); + } + for (SubCategoryDefinition subcat : subcategories) { + boolean foundSub = false; + if (subcat.getName().equals(subCategory.getName())) { + foundSub = true; + } + if (foundSub == false) { + subcategories.add(subCategory); + break; + } + } + } + } + } + if (foundCat == false) { + if (subCategory != null) { + category.addSubCategory(subCategory); + } + categories.add(category); + } + } + + public Map> getComponentInstancesAttributes() { + return componentInstancesAttributes; + } + + public void setComponentInstancesAttributes( + Map> componentInstancesAttributes) { + this.componentInstancesAttributes = componentInstancesAttributes; + } + + public Map> getComponentInstancesInputs() { + return componentInstancesInputs; + } + + public void setComponentInstancesInputs(Map> componentInstancesInputs) { + this.componentInstancesInputs = componentInstancesInputs; + } + + public void setSpecificComponetTypeArtifacts(Map specificComponentTypeArtifacts) { + // Implement where needed + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java new file mode 100644 index 0000000000..ce9ac67ced --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.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.model; + +import java.util.List; +import java.util.Map; + +public class ComponentInstInputsMap { + + Map> componentInstanceInputsMap; + + public Map> getComponentInstanceInputsMap() { + return componentInstanceInputsMap; + } + + public void setComponentInstanceInputsMap(Map> componentInstanceInputsMap) { + this.componentInstanceInputsMap = componentInstanceInputsMap; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java new file mode 100644 index 0000000000..baaf89bcfc --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.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.model; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; + +public class ComponentInstance extends ComponentInstanceDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6721465693884621223L; + + private String icon; + + private String componentName; + private String componentVersion; + private String toscaComponentName; + private Map> capabilities; + private Map> requirements; + private Map deploymentArtifacts; + + public ComponentInstance() { + super(); + } + + public ComponentInstance(ComponentInstanceDataDefinition r) { + super(r); + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getComponentName() { + return componentName; + } + + public void setComponentName(String resourceName) { + this.componentName = resourceName; + } + + public String getComponentVersion() { + return componentVersion; + } + + public String getToscaComponentName() { + return toscaComponentName; + } + + public void setToscaComponentName(String toscaComponentName) { + this.toscaComponentName = toscaComponentName; + } + + public void setComponentVersion(String resourceVersion) { + this.componentVersion = resourceVersion; + } + + 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; + } + + public Map getDeploymentArtifacts() { + return deploymentArtifacts; + } + + public void setDeploymentArtifacts(Map deploymentArtifacts) { + this.deploymentArtifacts = deploymentArtifacts; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java new file mode 100644 index 0000000000..12233e733c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.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.model; + +import java.io.Serializable; + +public class ComponentInstanceAttribute extends AttributeDefinition + implements IComponentInstanceConnectedElement, Serializable { + + /** + * + */ + private static final long serialVersionUID = -496828411269235795L; + + private Boolean hidden; + + /** + * The unique id of the attribute value on graph + */ + private String valueUniqueUid; + + public ComponentInstanceAttribute() { + super(); + } + + public ComponentInstanceAttribute(AttributeDefinition pd, Boolean hidden, String valueUniqueUid) { + super(pd); + + this.hidden = hidden; + this.valueUniqueUid = valueUniqueUid; + setParentUniqueId(pd.getParentUniqueId()); + } + + public String getValueUniqueUid() { + return valueUniqueUid; + } + + public void setValueUniqueUid(String valueUniqueUid) { + this.valueUniqueUid = valueUniqueUid; + } + + @Override + public String toString() { + return "ComponentInstanceAttribute [ " + super.toString() + " , value=" + hidden + ", valueUniqueUid = " + + valueUniqueUid + " ]"; + } + + public Boolean isHidden() { + return hidden; + } + + public void setHidden(Boolean hidden) { + this.hidden = hidden; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java new file mode 100644 index 0000000000..1334fa8c06 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.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.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; + +public class ComponentInstanceInput extends InputDefinition implements IComponentInstanceConnectedElement { + + /** + * Value of property + */ + private String value; + + /** + * The unique id of the property value on graph + */ + private String valueUniqueUid; + + private String inputId; + + private List path = null; + + private List rules = null; + private String componentInstanceName; + private String componentInstanceId; + + public ComponentInstanceInput() { + super(); + } + + public ComponentInstanceInput(PropertyDataDefinition curPropertyDef, String inputId, String value, + String valueUniqueUid) { + super(curPropertyDef); + this.inputId = inputId; + this.value = value; + this.valueUniqueUid = valueUniqueUid; + } + + public ComponentInstanceInput(InputDefinition pd, String value, String valueUniqueUid) { + super(pd); + + this.value = value; + this.valueUniqueUid = valueUniqueUid; + } + + public String getComponentInstanceName() { + return componentInstanceName; + } + + public void setComponentInstanceName(String componentInstanceName) { + this.componentInstanceName = componentInstanceName; + } + + public String getComponentInstanceId() { + return componentInstanceId; + } + + public void setComponentInstanceId(String componentInstanceId) { + this.componentInstanceId = componentInstanceId; + } + + public String getInputId() { + return inputId; + } + + public void setInputId(String inputId) { + this.inputId = inputId; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValueUniqueUid() { + return valueUniqueUid; + } + + public void setValueUniqueUid(String valueUniqueUid) { + this.valueUniqueUid = valueUniqueUid; + } + + public boolean isDefinition() { + return definition; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public List getPath() { + return path; + } + + public void setPath(List path) { + this.path = path; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + @Override + public String toString() { + return "ComponentInstanceInput [ " + super.toString() + " , value=" + value + ", valueUniqueUid = " + + valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java new file mode 100644 index 0000000000..a804170c75 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.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.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; + +public class ComponentInstanceProperty extends PropertyDefinition + implements IComponentInstanceConnectedElement, Serializable { + + /** + * + */ + private static final long serialVersionUID = -6559573536869242691L; + + /** + * Value of property + */ + private String value; + + /** + * The unique id of the property value on graph + */ + private String valueUniqueUid; + + private List path = null; + + private List rules = null; + + private List getInputValues; + + public ComponentInstanceProperty() { + super(); + } + + public ComponentInstanceProperty(PropertyDefinition pd, String value, String valueUniqueUid) { + super(pd); + + this.value = value; + this.valueUniqueUid = valueUniqueUid; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValueUniqueUid() { + return valueUniqueUid; + } + + public void setValueUniqueUid(String valueUniqueUid) { + this.valueUniqueUid = valueUniqueUid; + } + + public boolean isDefinition() { + return definition; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public List getPath() { + return path; + } + + public void setPath(List path) { + this.path = path; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + public List getGetInputValues() { + return getInputValues; + } + + public void setGetInputValues(List getInputValues) { + this.getInputValues = getInputValues; + } + + @Override + public String toString() { + return "ComponentInstanceProperty [ " + super.toString() + " , value=" + value + ", valueUniqueUid = " + + valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java new file mode 100644 index 0000000000..da3947b42f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.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.model; + +import java.io.Serializable; + +import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; + +public class ComponentMetadataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 3570763790267255590L; + + protected ComponentMetadataDataDefinition componentMetadataDataDefinition; + + public ComponentMetadataDefinition() { + + } + + public ComponentMetadataDefinition(ComponentMetadataDataDefinition component) { + this.componentMetadataDataDefinition = component; + } + + public ComponentMetadataDataDefinition getMetadataDataDefinition() { + return this.componentMetadataDataDefinition; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((componentMetadataDataDefinition == null) ? 0 : componentMetadataDataDefinition.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ComponentMetadataDefinition other = (ComponentMetadataDefinition) obj; + if (componentMetadataDataDefinition == null) { + if (other.componentMetadataDataDefinition != null) + return false; + } else if (!componentMetadataDataDefinition.equals(other.componentMetadataDataDefinition)) + return false; + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java new file mode 100644 index 0000000000..0227de5b50 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java @@ -0,0 +1,316 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; + +public class ComponentParametersView { + + boolean ignoreUsers = false; + boolean ignoreGroups = false; + boolean ignoreComponentInstances = false; + boolean ignoreComponentInstancesProperties = false; + boolean ignoreProperties = false; + boolean ignoreCapabilities = false; + boolean ignoreRequirements = false; + boolean ignoreCategories = false; + boolean ignoreAllVersions = false; + boolean ignoreAdditionalInformation = false; + boolean ignoreArtifacts = false; + boolean ignoreInterfaces = false; + boolean ignoreDerivedFrom = false; + boolean ignoreAttributesFrom = false; + boolean ignoreComponentInstancesAttributesFrom = false; + boolean ignoreInputs = false; + boolean ignoreComponentInstancesInputs = false; + + /////////////////////////////////////////////////////////////// + // When adding new member, please update the filter method. + /////////////////////////////////////////////////////////////// + + public Component filter(Component component, ComponentTypeEnum componentType) { + + if (ignoreUsers) { + component.setCreatorUserId(null); + component.setCreatorFullName(null); + component.setLastUpdaterUserId(null); + component.setLastUpdaterFullName(null); + } + + if (ignoreGroups) { + component.setGroups(null); + } + + if (ignoreComponentInstances) { + component.setComponentInstances(null); + component.setComponentInstancesRelations(null); + } + + if (ignoreComponentInstancesProperties) { + component.setComponentInstancesProperties(null); + } + + if (ignoreProperties) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setProperties(null); + break; + default: + break; + } + } + + if (ignoreCapabilities) { + component.setCapabilities(null); + } + + if (ignoreRequirements) { + component.setRequirements(null); + } + + if (ignoreCategories) { + component.setCategories(null); + } + + if (ignoreAllVersions) { + component.setAllVersions(null); + } + + if (ignoreAdditionalInformation) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setAdditionalInformation(null); + break; + default: + break; + } + } + + if (ignoreArtifacts) { + component.setArtifacts(null); + component.setSpecificComponetTypeArtifacts(null); + component.setDeploymentArtifacts(null); + component.setToscaArtifacts(null); + } + + if (ignoreInterfaces) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setInterfaces(null); + break; + default: + break; + } + } + + if (ignoreDerivedFrom) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setDerivedFrom(null); + break; + default: + break; + } + } + + if (ignoreAttributesFrom) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setAttributes(null); + break; + default: + break; + } + } + + if (ignoreComponentInstancesAttributesFrom) { + component.setComponentInstancesAttributes(null); + } + + if (ignoreInputs) { + component.setInputs(null); + } + + if (ignoreComponentInstancesInputs) { + component.setComponentInstancesInputs(null); + } + + return component; + + } + + public void disableAll() { + ignoreUsers = true; + ignoreGroups = true; + ignoreComponentInstances = true; + ignoreComponentInstancesProperties = true; + ignoreProperties = true; + ignoreCapabilities = true; + ignoreRequirements = true; + ignoreCategories = true; + ignoreAllVersions = true; + ignoreAdditionalInformation = true; + ignoreArtifacts = true; + ignoreInterfaces = true; + ignoreDerivedFrom = true; + ignoreAttributesFrom = true; + ignoreInputs = true; + ignoreComponentInstancesAttributesFrom = true; + ignoreComponentInstancesInputs = true; + } + + public boolean isIgnoreGroups() { + return ignoreGroups; + } + + public void setIgnoreGroups(boolean ignoreGroups) { + this.ignoreGroups = ignoreGroups; + } + + public boolean isIgnoreComponentInstances() { + return ignoreComponentInstances; + } + + public void setIgnoreComponentInstances(boolean ignoreComponentInstances) { + this.ignoreComponentInstances = ignoreComponentInstances; + } + + public boolean isIgnoreProperties() { + return ignoreProperties; + } + + public void setIgnoreProperties(boolean ignoreProperties) { + this.ignoreProperties = ignoreProperties; + } + + public boolean isIgnoreCapabilities() { + return ignoreCapabilities; + } + + public void setIgnoreCapabilities(boolean ignoreCapabilities) { + this.ignoreCapabilities = ignoreCapabilities; + } + + public boolean isIgnoreRequirements() { + return ignoreRequirements; + } + + public void setIgnoreRequirements(boolean ignoreRequirements) { + this.ignoreRequirements = ignoreRequirements; + } + + public boolean isIgnoreCategories() { + return ignoreCategories; + } + + public void setIgnoreCategories(boolean ignoreCategories) { + this.ignoreCategories = ignoreCategories; + } + + public boolean isIgnoreAllVersions() { + return ignoreAllVersions; + } + + public void setIgnoreAllVersions(boolean ignoreAllVersions) { + this.ignoreAllVersions = ignoreAllVersions; + } + + public boolean isIgnoreAdditionalInformation() { + return ignoreAdditionalInformation; + } + + public void setIgnoreAdditionalInformation(boolean ignoreAdditionalInformation) { + this.ignoreAdditionalInformation = ignoreAdditionalInformation; + } + + public boolean isIgnoreArtifacts() { + return ignoreArtifacts; + } + + public void setIgnoreArtifacts(boolean ignoreArtifacts) { + this.ignoreArtifacts = ignoreArtifacts; + } + + public boolean isIgnoreComponentInstancesProperties() { + return ignoreComponentInstancesProperties; + } + + public void setIgnoreComponentInstancesProperties(boolean ignoreComponentInstancesProperties) { + this.ignoreComponentInstancesProperties = ignoreComponentInstancesProperties; + } + + public boolean isIgnoreComponentInstancesInputs() { + return ignoreComponentInstancesInputs; + } + + public void setIgnoreComponentInstancesInputs(boolean ignoreComponentInstancesInputs) { + this.ignoreComponentInstancesInputs = ignoreComponentInstancesInputs; + } + + public boolean isIgnoreInterfaces() { + return ignoreInterfaces; + } + + public void setIgnoreInterfaces(boolean ignoreInterfaces) { + this.ignoreInterfaces = ignoreInterfaces; + } + + public boolean isIgnoreAttributesFrom() { + return ignoreAttributesFrom; + } + + public void setIgnoreAttributesFrom(boolean ignoreAttributesFrom) { + this.ignoreAttributesFrom = ignoreDerivedFrom; + } + + public boolean isIgnoreComponentInstancesAttributesFrom() { + return ignoreComponentInstancesAttributesFrom; + } + + public void setIgnoreComponentInstancesAttributesFrom(boolean ignoreComponentInstancesAttributesFrom) { + this.ignoreComponentInstancesAttributesFrom = ignoreComponentInstancesAttributesFrom; + } + + public boolean isIgnoreDerivedFrom() { + return ignoreDerivedFrom; + } + + public void setIgnoreDerivedFrom(boolean ignoreDerivedFrom) { + this.ignoreDerivedFrom = ignoreDerivedFrom; + } + + public boolean isIgnoreUsers() { + return ignoreUsers; + } + + public void setIgnoreUsers(boolean ignoreUsers) { + this.ignoreUsers = ignoreUsers; + } + + public boolean isIgnoreInputs() { + return ignoreInputs; + } + + public void setIgnoreInputs(boolean ignoreInputs) { + this.ignoreInputs = ignoreInputs; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java new file mode 100644 index 0000000000..eef455cbe2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.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.model; + +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; + +public class ConsumerDefinition extends ConsumerDataDefinition { + + public ConsumerDefinition() { + super(); + } + + public ConsumerDefinition(ConsumerDataDefinition a) { + super(a); + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java new file mode 100644 index 0000000000..972884682e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.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.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class DataTypeDefinition extends DataTypeDataDefinition { + + // @JsonIgnore + // @org.codehaus.jackson.annotate.JsonIgnore + private DataTypeDefinition derivedFrom; + + private List constraints; + + private List properties; + + public DataTypeDefinition() { + super(); + } + + public DataTypeDefinition(DataTypeDataDefinition p) { + super(p); + } + + public DataTypeDefinition(DataTypeDefinition pd) { + this.setName(pd.getName()); + this.setDerivedFrom(pd.getDerivedFrom()); + this.setDerivedFromName(pd.getDerivedFromName()); + this.setUniqueId(pd.getUniqueId()); + this.setConstraints(pd.getConstraints()); + this.setDescription(pd.getDescription()); + } + + public List getConstraints() { + return constraints; + } + + public void setConstraints(List constraints) { + this.constraints = constraints; + } + + public DataTypeDefinition getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(DataTypeDefinition derivedFrom) { + this.derivedFrom = derivedFrom; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + @Override + public String toString() { + return super.toString() + " DataTypeDefinition [derivedFrom=" + derivedFrom + ", constraints=" + constraints + + ", properties=" + properties + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java new file mode 100644 index 0000000000..89b5bfff31 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.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.model; + +public enum DistributionStatusEnum { + DISTRIBUTION_NOT_APPROVED("Distribution not approved"), + DISTRIBUTION_APPROVED("Distribution approved"), + DISTRIBUTED("Distributed"), + DISTRIBUTION_REJECTED("Distribution rejected"); + + private String value; + + private DistributionStatusEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static DistributionStatusEnum findState(String state) { + + for (DistributionStatusEnum distributionStatus : DistributionStatusEnum.values()) { + if (distributionStatus.name().equalsIgnoreCase(state) + || distributionStatus.getValue().equalsIgnoreCase(state)) { + return distributionStatus; + } + } + return null; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java new file mode 100644 index 0000000000..05f69f3166 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.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.be.model; + +public enum DistributionTransitionEnum { + APPROVE("approve"), REJECT("reject"); + + String displayName; + + private DistributionTransitionEnum(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + + public static DistributionTransitionEnum getFromDisplayName(String name) { + + for (DistributionTransitionEnum val : DistributionTransitionEnum.values()) { + if (name.equalsIgnoreCase(val.getDisplayName())) { + return val; + } + } + return null; + } + + public static String valuesAsString() { + StringBuilder sb = new StringBuilder(); + for (DistributionTransitionEnum op : DistributionTransitionEnum.values()) { + sb.append(op.getDisplayName()).append(" "); + } + return sb.toString(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java new file mode 100644 index 0000000000..5aa3b85d02 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.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.model; + +public class FunctionalMenuInfo { + + private String functionalMenu; + + public FunctionalMenuInfo() { + super(); + } + + public String getFunctionalMenu() { + return functionalMenu; + } + + public void setFunctionalMenu(String functionalMenu) { + this.functionalMenu = functionalMenu; + } + + @Override + public String toString() { + return "FunctionalMenuInfo [functionalMenu=" + functionalMenu + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GetInputValueInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GetInputValueInfo.java new file mode 100644 index 0000000000..bb53e13251 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GetInputValueInfo.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.model; + +public class GetInputValueInfo { + String propName; + String inputName; + Integer indexValue; + GetInputValueInfo getInputIndex; + + boolean isList = false; + + public String getPropName() { + return propName; + } + + public void setPropName(String propName) { + this.propName = propName; + } + + public String getInputName() { + return inputName; + } + + public void setInputName(String inputName) { + this.inputName = inputName; + } + + public Integer getIndexValue() { + return indexValue; + } + + public void setIndexValue(Integer indexValue) { + this.indexValue = indexValue; + } + + public GetInputValueInfo getGetInputIndex() { + return getInputIndex; + } + + public void setGetInputIndex(GetInputValueInfo getInputIndex) { + this.getInputIndex = getInputIndex; + } + + public boolean isList() { + return isList; + } + + public void setList(boolean isList) { + this.isList = isList; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java new file mode 100644 index 0000000000..5520e89032 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.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.be.model; + +import java.io.Serializable; +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; + +public class GroupDefinition extends GroupDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -852613634651112247L; + + // map of componentInstances + private Map members; + + // properties (properties should be defined in the group type, the + // properties here are actually the value for the properties) + private List properties; + + // artifacts - list of artifact uid. All artifacts in the group must already + // be uploaded to the VF + private List artifacts; + + private List artifactsUuid; + + // The unique id of the type of this group + private String typeUid; + + public GroupDefinition() { + super(); + } + + public GroupDefinition(GroupDataDefinition other) { + super(other); + } + + public GroupDefinition(GroupDefinition other) { + this.setName(other.getName()); + this.setUniqueId(other.getUniqueId()); + this.setType(other.getType()); + this.setVersion(other.getVersion()); + this.setInvariantUUID(other.getInvariantUUID()); + this.setGroupUUID(other.getGroupUUID()); + this.setDescription(other.getDescription()); + if (other.members != null) { + this.members = new HashMap(other.getMembers()); + } + if (other.properties != null) { + this.properties = other.properties.stream().map(p -> new GroupProperty(p)).collect(Collectors.toList()); + } + if (other.artifacts != null) { + this.artifacts = new ArrayList(other.getArtifacts()); + } + + if (other.artifactsUuid != null) { + this.artifactsUuid = new ArrayList(other.getArtifactsUuid()); + } + this.setTypeUid(other.typeUid); + } + + public Map getMembers() { + return members; + } + + public void setMembers(Map members) { + this.members = members; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + public String getTypeUid() { + return typeUid; + } + + public void setTypeUid(String typeUid) { + this.typeUid = typeUid; + } + + public List getArtifactsUuid() { + return artifactsUuid; + } + + public void setArtifactsUuid(List artifactsUuid) { + this.artifactsUuid = artifactsUuid; + } + + @Override + public String toString() { + return "GroupDefinition [" + super.toString() + "members=" + members + ", properties=" + properties + + ", artifacts=" + artifacts + ", artifactsUUID=" + artifactsUuid + ", typeUid=" + typeUid + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java new file mode 100644 index 0000000000..cf0afde8e3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.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.model; + +public class GroupProperty extends PropertyDefinition { + + /** + * current value + */ + private String value; + + /** + * The unique is of Group property on graph. If it is null, then the + * property's value was not updated. The value is taken from the group type + * property. + */ + private String valueUniqueUid; + + public GroupProperty() { + super(); + } + + public GroupProperty(PropertyDefinition pd, String value, String valueUniqueUid) { + super(pd); + this.value = value; + this.valueUniqueUid = valueUniqueUid; + } + + public GroupProperty(GroupProperty other) { + super(other); + if (other != null) { + this.value = other.getValue(); + this.valueUniqueUid = other.getValueUniqueUid(); + } + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValueUniqueUid() { + return valueUniqueUid; + } + + public void setValueUniqueUid(String valueUniqueUid) { + this.valueUniqueUid = valueUniqueUid; + } + + @Override + public String toString() { + return "GroupProperty [ " + super.toString() + " , value=" + value + ", valueUniqueUid = " + valueUniqueUid + + " ]"; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java new file mode 100644 index 0000000000..cd7fd6401b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.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.be.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.GroupTypeDataDefinition; + +/** + * Specifies the group type that the Node Type exposes. + */ +public class GroupTypeDefinition extends GroupTypeDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -1597773317924162703L; + + private List properties; + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public GroupTypeDefinition() { + super(); + } + + public GroupTypeDefinition(GroupTypeDataDefinition p) { + super(p); + } + + @Override + public String toString() { + return super.toString() + " [ properties=" + properties + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java new file mode 100644 index 0000000000..8e03361027 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.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.model; + +import java.io.Serializable; + +import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition; + +public class HeatParameterDefinition extends HeatParameterDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 3400360721469962105L; + + public HeatParameterDefinition(HeatParameterDataDefinition hpdd) { + super(hpdd); + } + + public HeatParameterDefinition() { + super(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java new file mode 100644 index 0000000000..3d21e07408 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.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.model; + +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; + +public interface IComplexDefaultValue { + String getType(); + + String getName(); + + String getDefaultValue(); + + void setDefaultValue(String value); + + SchemaDefinition getSchema(); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java new file mode 100644 index 0000000000..86de3a1584 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.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.model; + +public interface IComponentInstanceConnectedElement { + String getUniqueId(); + + String getValueUniqueUid(); + + void setValueUniqueUid(String value); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java new file mode 100644 index 0000000000..1419353189 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.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.model; + +/** + * An operation parameter can be either a PropertyValue (value or expression) or + * a PropertyDefinition. + */ +public interface IOperationParameter { + /** + * Allow to know if the operation parameter is a property definition or a + * property value. Only parameter exposed as property definitions can be + * used for "custom" operations. + * + * @return true if the operation parameter is a property definition and + * false if the parameter is a property value. + */ + boolean isDefinition(); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java new file mode 100644 index 0000000000..fb5943e1bd --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +/** + * Specifies an implementation artifact for interfaces or operations of a + * {@link NodeType node type} or {@link RelationshipType relation type}. + * + * @author esofer + */ +public class ImplementationArtifact { + /** + *

+ * Specifies the type of this artifact. + *

+ */ + private String artifactType; + + /** + *

+ * Identifies an Artifact Template to be used as implementation artifact. + * This Artifact Template can be defined in the same Definitions document or + * in a separate, imported document. + *

+ * + *

+ * The type of Artifact Template referenced by the artifactRef attribute + * MUST be the same type or a sub-type of the type specified in the + * artifactType attribute. + *

+ * + *

+ * Note: if no Artifact Template is referenced, the artifact type specific + * content of the ImplementationArtifact element alone is assumed to + * represent the actual artifact. For example, a simple script could be + * defined in place within the ImplementationArtifact element. + *

+ */ + private String artifactRef; + + /** + * The name of the archive in which the artifact lies. + */ + private String archiveName; + /** + * The version of the archive in which the artifact lies. + */ + private String archiveVersion; +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java new file mode 100644 index 0000000000..3090d7232e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.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.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; + +public class InputDefinition extends PropertyDefinition { + String label; + Boolean hidden; + Boolean immutable; + List inputsValue; + List properties; + + public InputDefinition() { + super(); + // TODO Auto-generated constructor stub + } + + public InputDefinition(PropertyDataDefinition p) { + super(p); + // TODO Auto-generated constructor stub + } + + public InputDefinition(PropertyDefinition pd) { + super(pd); + // TODO Auto-generated constructor stub + } + + public Boolean isHidden() { + return hidden; + } + + public void setHidden(Boolean hidden) { + this.hidden = hidden; + } + + public Boolean isImmutable() { + return immutable; + } + + public void setImmutable(Boolean immutable) { + this.immutable = immutable; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public List getInputsValue() { + return inputsValue; + } + + public void setInputsValue(List inputsValue) { + this.inputsValue = inputsValue; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java new file mode 100644 index 0000000000..51ad31199a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.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.model; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; + +/** + * Definition of the operations that can be performed on (instances of) a Node + * Type. + * + * @author esofer + */ +public class InterfaceDefinition extends InterfaceDataDefinition implements IOperationParameter, Serializable { + + /** + * + */ + private static final long serialVersionUID = 8220887972866354746L; + + /** + * Defines an operation available to manage particular aspects of the Node + * Type. + */ + private Map operations = new HashMap(); + + private boolean definition; + + public InterfaceDefinition() { + super(); + // TODO Auto-generated constructor stub + } + + public InterfaceDefinition(String type, String description, Map operations) { + super(type, description); + this.operations = operations; + + } + + public InterfaceDefinition(InterfaceDataDefinition p) { + super(p); + // TODO Auto-generated constructor stub + } + + @Override + public boolean isDefinition() { + // TODO Auto-generated method stub + return false; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public Map getOperations() { + return operations; + } + + public void setOperations(Map operations) { + this.operations = operations; + } + + @Override + public String toString() { + return "InterfaceDefinition [operations=" + operations + ", definition=" + definition + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java new file mode 100644 index 0000000000..7d135c5f8e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.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.model; + +public enum LifeCycleTransitionEnum { + + CHECKOUT("checkout"), + CHECKIN("checkin"), + CERTIFICATION_REQUEST("certificationRequest"), + UNDO_CHECKOUT("undoCheckout"), + CANCEL_CERTIFICATION("cancelCertification"), + START_CERTIFICATION("startCertification"), + FAIL_CERTIFICATION("failCertification"), + CERTIFY("certify"), + DISTRIBUTE("distribute"); + + String displayName; + + private LifeCycleTransitionEnum(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + + public static LifeCycleTransitionEnum getFromDisplayName(String name) { + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CHECKOUT.getDisplayName())) { + return LifeCycleTransitionEnum.CHECKOUT; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CHECKIN.getDisplayName())) { + return LifeCycleTransitionEnum.CHECKIN; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CERTIFICATION_REQUEST.getDisplayName())) { + return LifeCycleTransitionEnum.CERTIFICATION_REQUEST; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.UNDO_CHECKOUT.getDisplayName())) { + return LifeCycleTransitionEnum.UNDO_CHECKOUT; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CANCEL_CERTIFICATION.getDisplayName())) { + return LifeCycleTransitionEnum.CANCEL_CERTIFICATION; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.START_CERTIFICATION.getDisplayName())) { + return LifeCycleTransitionEnum.START_CERTIFICATION; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.FAIL_CERTIFICATION.getDisplayName())) { + return LifeCycleTransitionEnum.FAIL_CERTIFICATION; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CERTIFY.getDisplayName())) { + return LifeCycleTransitionEnum.CERTIFY; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.DISTRIBUTE.getDisplayName())) { + return LifeCycleTransitionEnum.DISTRIBUTE; + } else + throw new IllegalArgumentException(name + " value does not match any of LifeCycleTransitionEnum values"); + } + + public static String valuesAsString() { + StringBuilder sb = new StringBuilder(); + for (LifeCycleTransitionEnum op : LifeCycleTransitionEnum.values()) { + sb.append(op.getDisplayName()).append(" "); + } + return sb.toString(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java new file mode 100644 index 0000000000..4d9ef81452 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.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.model; + +public enum LifecycleStateEnum { + + READY_FOR_CERTIFICATION, + + CERTIFICATION_IN_PROGRESS, + + CERTIFIED, + + NOT_CERTIFIED_CHECKIN, + + NOT_CERTIFIED_CHECKOUT; + + public static LifecycleStateEnum findState(String state) { + + for (LifecycleStateEnum lifecycleStateEnum : LifecycleStateEnum.values()) { + if (lifecycleStateEnum.name().equals(state)) { + return lifecycleStateEnum; + } + } + return null; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java new file mode 100644 index 0000000000..a793c68528 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.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.be.model; + +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InputsValueDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; + +/** + * Defines an operation available to manage particular aspects of the Node Type. + * + * @author esofer + */ +public class Operation extends OperationDataDefinition implements IOperationParameter { + + /** Implementation artifact for the interface. */ + private ArtifactDefinition implementation; + + /** + * This OPTIONAL property contains a list of one or more input parameter + * definitions. + */ + // @JsonDeserialize(contentUsing = OperationParameterDeserializer.class) + private Map inputs; + + private boolean definition; + + /** + *

+ * Jackson DeSerialization workaround constructor to create an operation + * with no arguments. + *

+ * + * @param emptyString + * The empty string provided by jackson. + */ + public Operation() { + super(); + // TODO Auto-generated constructor stub + } + + public Operation(OperationDataDefinition p) { + super(p); + // TODO Auto-generated constructor stub + } + + public Operation(ArtifactDataDefinition implementation, String description, + Map inputs) { + super(description); + + } + + @Override + public boolean isDefinition() { + // TODO Auto-generated method stub + return false; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public ArtifactDefinition getImplementation() { + return implementation; + } + + public void setImplementation(ArtifactDefinition implementation) { + this.implementation = implementation; + } + + public Map getInputs() { + return inputs; + } + + public void setInputs(Map inputs) { + this.inputs = inputs; + } + + @Override + public String toString() { + return "Operation [implementation=" + implementation + ", inputs=" + inputs + ", definition=" + definition + + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java new file mode 100644 index 0000000000..3b0708168b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.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.be.model; + +import java.util.Map; + +public class ParsedToscaYamlInfo { + Map inputs; + + Map instances; + + Map groups; + + public Map getInstances() { + return instances; + } + + public void setInstances(Map instances) { + this.instances = instances; + } + + public Map getGroups() { + return groups; + } + + public void setGroups(Map groups) { + this.groups = groups; + } + + public Map getInputs() { + return inputs; + } + + public void setInputs(Map inputs) { + this.inputs = inputs; + } + + @Override + public String toString() { + return "ParsedToscaYamlInfo [inputs=" + inputs + ", instances=" + instances + ", groups=" + groups + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java new file mode 100644 index 0000000000..e609f49321 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.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.model; + +public class Point { + + String x; + String y; + + public Point() { + super(); + } + + public Point(String x, String y) { + super(); + this.x = x; + this.y = y; + } + + public String getX() { + return x; + } + + public void setX(String x) { + this.x = x; + } + + public String getY() { + return y; + } + + public void setY(String y) { + this.y = y; + } + + @Override + public String toString() { + return "Point [x=" + x + ", y=" + y + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java new file mode 100644 index 0000000000..9b3e72ccc6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.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.be.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition; + +/** + * Specifies the policy type that the Node Type exposes. + */ +public class PolicyTypeDefinition extends PolicyTypeDataDefinition { + + private List properties; + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public PolicyTypeDefinition() { + super(); + } + + public PolicyTypeDefinition(PolicyTypeDataDefinition p) { + super(p); + } + + @Override + public String toString() { + return super.toString() + " [ properties=" + properties + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java new file mode 100644 index 0000000000..04223857b7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.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.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.ProductMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; + +public class Product extends Component { + + public Product() { + super(new ProductMetadataDefinition()); + componentType = ComponentTypeEnum.PRODUCT; + } + + public Product(ProductMetadataDefinition productMetadataDefinition) { + super(productMetadataDefinition); + componentType = ComponentTypeEnum.PRODUCT; + } + + public String getFullName() { + return getProductMetadataDefinition().getFullName(); + } + + public void setFullName(String fullName) { + getProductMetadataDefinition().setFullName(fullName); + } + + public String getInvariantUUID() { + return getProductMetadataDefinition().getInvariantUUID(); + } + + public void setInvariantUUID(String invariantUUID) { + getProductMetadataDefinition().setInvariantUUID(invariantUUID); + } + + public List getContacts() { + return getProductMetadataDefinition().getContacts(); + } + + public void setContacts(List contacts) { + getProductMetadataDefinition().setContacts(contacts); + } + + public void addContact(String contact) { + getProductMetadataDefinition().addContact(contact); + } + + public Boolean getIsActive() { + return getProductMetadataDefinition().getIsActive(); + } + + public void setIsActive(Boolean isActive) { + getProductMetadataDefinition().setIsActive(isActive); + } + + private ProductMetadataDataDefinition getProductMetadataDefinition() { + return (ProductMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java new file mode 100644 index 0000000000..dc454d13b7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.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.model; + +import org.openecomp.sdc.be.datatypes.elements.ProductMetadataDataDefinition; + +public class ProductMetadataDefinition extends ComponentMetadataDefinition { + + public ProductMetadataDefinition() { + super(); + this.componentMetadataDataDefinition = new ProductMetadataDataDefinition(); + } + + public ProductMetadataDefinition(ProductMetadataDataDefinition component) { + super(component); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java new file mode 100644 index 0000000000..b1e1552dfa --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public interface PropertyConstraint { + + void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException; + + void validate(Object propertyValue) throws ConstraintViolationException; + + void validate(ToscaType toscaType, String propertyTextValue) throws ConstraintViolationException; +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java new file mode 100644 index 0000000000..7974e863ac --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.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.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; + +//import javax.validation.Valid; +//import javax.validation.constraints.NotNull; +// +// +//import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +//import com.fasterxml.jackson.annotation.JsonProperty; +//import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +public class PropertyDefinition extends PropertyDataDefinition + implements IOperationParameter, IComplexDefaultValue, Serializable { + + /** + * + */ + private static final long serialVersionUID = 188403656600317269L; + + private List constraints; + // private Schema schema; + private String status; + + private String name; + + /** + * The resource id which this property belongs to + */ + private String parentUniqueId; + + public PropertyDefinition() { + super(); + } + + public PropertyDefinition(PropertyDataDefinition p) { + super(p); + } + + public PropertyDefinition(PropertyDefinition pd) { + this.setUniqueId(pd.getUniqueId()); + this.setConstraints(pd.getConstraints()); + // this.setSchema(pd.schema); + this.setDefaultValue(pd.getDefaultValue()); + this.setDescription(pd.getDescription()); + this.setName(pd.getName()); + this.setSchema(pd.getSchema()); + this.setParentUniqueId(pd.getParentUniqueId()); + this.setRequired(pd.isRequired()); + this.setType(pd.getType()); + } + + public List getConstraints() { + return constraints; + } + + public void setConstraints(List constraints) { + this.constraints = constraints; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return super.toString() + " [name=" + name + ", parentUniqueId=" + parentUniqueId + ", constraints=" + + constraints + "]]"; + } + + // public void setSchema(Schema entrySchema) { + // this.schema = entrySchema; + // + // } + // + // public Schema getSchema() { + // return schema; + // } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getParentUniqueId() { + return parentUniqueId; + } + + public void setParentUniqueId(String parentUniqueId) { + this.parentUniqueId = parentUniqueId; + } + + @Override + public boolean isDefinition() { + return false; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((constraints == null) ? 0 : constraints.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((parentUniqueId == null) ? 0 : parentUniqueId.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + PropertyDefinition other = (PropertyDefinition) obj; + if (constraints == null) { + if (other.constraints != null) + return false; + } else if (!constraints.equals(other.constraints)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (parentUniqueId == null) { + if (other.parentUniqueId != null) + return false; + } else if (!parentUniqueId.equals(other.parentUniqueId)) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java new file mode 100644 index 0000000000..e46c433291 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.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.be.model; + +public class PropertyScope { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PropertyScope other = (PropertyScope) obj; + if (name == null) { + if (other.getClass() != null) { + return false; + } + } else if (!name.equals(other.getName())) { + return false; + } + return true; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java new file mode 100644 index 0000000000..0c322420b3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.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.model; + +import org.openecomp.sdc.be.datatypes.elements.InputsValueDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; + +public class PropertyValueDefinition extends InputsValueDataDefinition implements IOperationParameter { + + public PropertyValueDefinition() { + super(); + // TODO Auto-generated constructor stub + } + + public PropertyValueDefinition(String name, String value) { + super(name, value); + + } + + @Override + public boolean isDefinition() { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java new file mode 100644 index 0000000000..6028809454 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.io.Serializable; + +public class RelationshipImpl implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -8272341490256251337L; + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public String toString() { + return "RelationshipImpl [type=" + type + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementAndRelationshipPair.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementAndRelationshipPair.java new file mode 100644 index 0000000000..84ead66658 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementAndRelationshipPair.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.model; + +import java.io.Serializable; + +public class RequirementAndRelationshipPair implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -5763126570618602135L; + + private String requirement; + private String capabilityOwnerId; + private String requirementOwnerId; + + private RelationshipImpl relationship; + + private String capability; + + private String capabilityUid; + private String requirementUid; + + public RequirementAndRelationshipPair() { + super(); + } + + public RequirementAndRelationshipPair(String requirement, RelationshipImpl relationship) { + super(); + this.requirement = requirement; + this.relationship = relationship; + } + + public RequirementAndRelationshipPair(String requirement, RelationshipImpl relationship, String capability) { + super(); + this.requirement = requirement; + this.relationship = relationship; + this.capability = capability; + } + + public String getRequirement() { + return requirement; + } + + public void setRequirement(String requirement) { + this.requirement = requirement; + } + + public String getCapabilityOwnerId() { + return capabilityOwnerId; + } + + public void setCapabilityOwnerId(String capabilityOwnerId) { + this.capabilityOwnerId = capabilityOwnerId; + } + + public String getRequirementOwnerId() { + return requirementOwnerId; + } + + public void setRequirementOwnerId(String requirementOwnerId) { + this.requirementOwnerId = requirementOwnerId; + } + + public RelationshipImpl getRelationship() { + return relationship; + } + + public void setRelationships(RelationshipImpl relationship) { + this.relationship = relationship; + } + + public String getCapability() { + return capability; + } + + public void setCapability(String capability) { + this.capability = capability; + } + + public String getCapabilityUid() { + return capabilityUid; + } + + public void setCapabilityUid(String capabilityUid) { + this.capabilityUid = capabilityUid; + } + + public String getRequirementUid() { + return requirementUid; + } + + public void setRequirementUid(String requirementUid) { + this.requirementUid = requirementUid; + } + + @Override + public String toString() { + return "RequirementAndRelationshipPair [requirement=" + requirement + ", relationship=" + relationship + + ", capability=" + capability + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java new file mode 100644 index 0000000000..345f2721ff --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.io.Serializable; + +public class RequirementCapabilityRelDef extends TargetCapabilityRelDef implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -6396265049494824741L; + + private String fromNode; + + public String getFromNode() { + return fromNode; + } + + public void setFromNode(String fromNode) { + this.fromNode = fromNode; + } + + @Override + public String toString() { + return "RequirementCapabilityRelDef [fromNode=" + fromNode + ", toString()=" + super.toString() + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java new file mode 100644 index 0000000000..3d5741255a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java @@ -0,0 +1,241 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.io.Serializable; + +/** + * Specifies the requirements that the Node Type exposes. + */ +public class RequirementDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -8840549489409274532L; + + /** + * Unique id of the requirement + */ + private String uniqueId; + + private String name; + + /** + * specify the capability type + */ + private String capability; + + /** + * specify the node type(Optional by tosca) + */ + private String node; + + /** + * specify the relationship type(Optional by tosca) + */ + private String relationship; + + // specifies the resource instance holding this requirement + private String ownerId; + private String ownerName; + + private String minOccurrences; + private String maxOccurrences; + + public RequirementDefinition() { + super(); + } + + public RequirementDefinition(RequirementDefinition other) { + this.uniqueId = other.uniqueId; + this.name = other.name; + this.capability = other.capability; + this.node = other.node; + this.relationship = other.relationship; + this.ownerId = other.ownerId; + this.ownerName = other.ownerName; + this.minOccurrences = other.minOccurrences; + this.maxOccurrences = other.maxOccurrences; + + } + + 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 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 RequirementImplDef getRequirementImpl() { + // return requirementImpl; + // } + // + // public void setRequirementImpl(RequirementImplDef requirementImpl) { + // this.requirementImpl = requirementImpl; + // } + + public String getOwnerId() { + return ownerId; + } + + public void setOwnerId(String ownerId) { + this.ownerId = ownerId; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public String getMinOccurrences() { + return minOccurrences; + } + + public void setMinOccurrences(String minOccurrences) { + this.minOccurrences = minOccurrences; + } + + public String getMaxOccurrences() { + return maxOccurrences; + } + + public void setMaxOccurrences(String maxOccurrences) { + this.maxOccurrences = maxOccurrences; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((capability == null) ? 0 : capability.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((node == null) ? 0 : node.hashCode()); + result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode()); + result = prime * result + ((ownerName == null) ? 0 : ownerName.hashCode()); + result = prime * result + ((relationship == null) ? 0 : relationship.hashCode()); + result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode()); + result = prime * result + ((minOccurrences == null) ? 0 : minOccurrences.hashCode()); + result = prime * result + ((maxOccurrences == null) ? 0 : maxOccurrences.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RequirementDefinition other = (RequirementDefinition) obj; + if (capability == null) { + if (other.capability != null) + return false; + } else if (!capability.equals(other.capability)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (node == null) { + if (other.node != null) + return false; + } else if (!node.equals(other.node)) + return false; + if (ownerId == null) { + if (other.ownerId != null) + return false; + } else if (!ownerId.equals(other.ownerId)) + return false; + if (ownerName == null) { + if (other.ownerName != null) + return false; + } else if (!ownerName.equals(other.ownerName)) + return false; + if (relationship == null) { + if (other.relationship != null) + return false; + } else if (!relationship.equals(other.relationship)) + return false; + if (uniqueId == null) { + if (other.uniqueId != null) + return false; + } else if (!uniqueId.equals(other.uniqueId)) + return false; + if (minOccurrences == null) { + if (other.minOccurrences != null) + return false; + } else if (!minOccurrences.equals(other.minOccurrences)) + return false; + if (maxOccurrences == null) { + if (other.maxOccurrences != null) + return false; + } else if (!maxOccurrences.equals(other.maxOccurrences)) + return false; + return true; + } + + @Override + public String toString() { + return "RequirementDefinition [uniqueId=" + uniqueId + ", name=" + name + ", capability=" + capability + + ", node=" + node + ", relationship=" + relationship + ", ownerId=" + ownerId + ", ownerName=" + + ownerName + ", minOccurrences=" + minOccurrences + ", maxOccurrences=" + maxOccurrences + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java new file mode 100644 index 0000000000..eb6bd01d4b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.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.model; + +import java.util.Map; + +public class RequirementImplDef { + + private String uniqueId; + + /** + * node type(mandatory). Unique id of the node we choose. + */ + private String nodeId; + + private Map requirementProperties; + + private Point point; + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public Map getRequirementProperties() { + return requirementProperties; + } + + public void setRequirementProperties(Map requirementProperties) { + this.requirementProperties = requirementProperties; + } + + public Point getPoint() { + return point; + } + + public void setPoint(Point point) { + this.point = point; + } + + @Override + public String toString() { + return "RequirementImplDef [uniqueId=" + uniqueId + ", nodeId=" + nodeId + ", requirementProperties=" + + requirementProperties + ", point=" + point + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java new file mode 100644 index 0000000000..14f4463216 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.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.model; + +/** + * Specifies the requirements that the Node Type exposes. + */ +public class RequirementInstance { + + /** + * specify the resource instance name as appears in the service + */ + private String node; + + /** + * specify the relationship impl + */ + private RelationshipImpl relationship; + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + + public RelationshipImpl getRelationship() { + return relationship; + } + + public void setRelationship(RelationshipImpl relationship) { + this.relationship = relationship; + } + + @Override + public String toString() { + return "RequirementInstance [node=" + node + ", relationship=" + relationship + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java new file mode 100644 index 0000000000..6490fb4ef1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java @@ -0,0 +1,273 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.io.Serializable; +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; + +public class Resource extends Component implements Serializable { + /** + * + */ + private static final long serialVersionUID = -6811540567661368482L; + + public Resource() { + super(new ResourceMetadataDefinition()); + componentType = ComponentTypeEnum.RESOURCE; + } + + public Resource(ComponentMetadataDefinition componentMetadataDefinition) { + super(componentMetadataDefinition); + componentType = ComponentTypeEnum.RESOURCE; + } + + private List derivedFrom; + + private List derivedList; + + private List properties; + + private List attributes; + + // Later + private Map interfaces; + + private List defaultCapabilities; + + private List additionalInformation; + + /** + * Please note that more than one "derivedFrom" resource is not currently + * supported by the app. The first list element is always addressed. + * + * @return + */ + public List getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(List derivedFrom) { + this.derivedFrom = derivedFrom; + } + + /** + * The derivedList is a chain of derivedFrom. e.g. if resource C is derived + * from resource B that is derived from resource A - then A, B is the + * "DerivedList" of resource C + * + * @return + */ + public List getDerivedList() { + return derivedList; + } + + public void setDerivedList(List derivedList) { + this.derivedList = derivedList; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public List getAttributes() { + return attributes; + } + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + + public Map getInterfaces() { + return interfaces; + } + + public void setInterfaces(Map interfaces) { + this.interfaces = interfaces; + } + + public Boolean isAbstract() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .isAbstract(); + } + + public void setAbstract(Boolean isAbstract) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setAbstract(isAbstract); + } + + public List getDefaultCapabilities() { + return defaultCapabilities; + } + + public void setDefaultCapabilities(List defaultCapabilities) { + this.defaultCapabilities = defaultCapabilities; + } + + public String getCost() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getCost(); + } + + public void setCost(String cost) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()).setCost(cost); + ; + } + + public String getLicenseType() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getLicenseType(); + } + + public void setLicenseType(String licenseType) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setLicenseType(licenseType); + } + + public List getAdditionalInformation() { + return additionalInformation; + } + + public void setAdditionalInformation(List additionalInformation) { + this.additionalInformation = additionalInformation; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + super.hashCode(); + + result = prime * result + ((attributes == null) ? 0 : attributes.hashCode()); + // result = prime * result + ((capabilities == null) ? 0 : + // capabilities.hashCode()); + result = prime * result + ((defaultCapabilities == null) ? 0 : defaultCapabilities.hashCode()); + result = prime * result + ((derivedFrom == null) ? 0 : derivedFrom.hashCode()); + result = prime * result + ((interfaces == null) ? 0 : interfaces.hashCode()); + result = prime * result + ((properties == null) ? 0 : properties.hashCode()); + result = prime * result + ((derivedList == null) ? 0 : derivedList.hashCode()); + // result = prime * result + ((requirements == null) ? 0 : + // requirements.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + Resource other = (Resource) obj; + if (attributes == null) { + if (other.attributes != null) + return false; + } else if (!attributes.equals(other.attributes)) + return false; + if (defaultCapabilities == null) { + if (other.defaultCapabilities != null) + return false; + } else if (!defaultCapabilities.equals(other.defaultCapabilities)) + return false; + if (derivedFrom == null) { + if (other.derivedFrom != null) + return false; + } else if (!derivedFrom.equals(other.derivedFrom)) + return false; + if (derivedList == null) { + if (other.derivedList != null) + return false; + } else if (!derivedList.equals(other.derivedList)) + return false; + if (interfaces == null) { + if (other.interfaces != null) + return false; + } else if (!interfaces.equals(other.interfaces)) + return false; + if (properties == null) { + if (other.properties != null) + return false; + } else if (!properties.equals(other.properties)) + return false; + + return super.equals(obj); + } + + @Override + public String toString() { + return "Resource [derivedFrom=" + derivedFrom + ", properties=" + properties + ", attributes=" + attributes + + ", interfaces=" + interfaces + // + ", capabilities=" + capabilities + ", requirements=" + + // requirements + + ", defaultCapabilities=" + defaultCapabilities + ", additionalInformation=" + additionalInformation + + "Metadata [" + getComponentMetadataDefinition().getMetadataDataDefinition().toString() + "]"; + } + + public String getToscaResourceName() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getToscaResourceName(); + } + + public void setToscaResourceName(String toscaResourceName) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setToscaResourceName(toscaResourceName); + } + + public ResourceTypeEnum getResourceType() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getResourceType(); + } + + public void setResourceType(ResourceTypeEnum resourceType) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setResourceType(resourceType); + } + + public void setVendorName(String vendorName) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setVendorName(vendorName); + } + + public void setVendorRelease(String vendorRelease) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setVendorRelease(vendorRelease); + } + + public String getVendorName() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getVendorName(); + } + + public String getVendorRelease() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getVendorRelease(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java new file mode 100644 index 0000000000..75dfdff444 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.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.model; + +public class ResourceInstanceHeatParameter extends HeatParameterDefinition { + + private String valueUniqueId; + + public ResourceInstanceHeatParameter() { + super(); + } + + public ResourceInstanceHeatParameter(HeatParameterDefinition heatParameterDefinition, String valueId) { + super(heatParameterDefinition); + valueUniqueId = valueId; + } + + public String getValueUniqueId() { + return valueUniqueId; + } + + public void setValueUniqueId(String valueUniqueId) { + this.valueUniqueId = valueUniqueId; + } + + @Override + public String toString() { + return "ResourceInstanceHeatParameter [ " + super.toString() + " , valueUniqueId = " + valueUniqueId + " ]"; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java new file mode 100644 index 0000000000..2448191fc9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.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.model; + +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; + +public class ResourceMetadataDefinition extends ComponentMetadataDefinition { + + public ResourceMetadataDefinition() { + super(); + this.componentMetadataDataDefinition = new ResourceMetadataDataDefinition(); + } + + public ResourceMetadataDefinition(ResourceMetadataDataDefinition other) { + super(other); + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java new file mode 100644 index 0000000000..cce4820870 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.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.model; + +import java.util.List; +import java.util.Map; + +/** + * Schema allows to create new types that can be used along TOSCA definitions. + */ +public class Schema { + private String derivedFrom; + private List constraints; + private Map properties; + private PropertyDefinition property; + + public PropertyDefinition getProperty() { + return property; + } + + public void setProperty(PropertyDefinition property) { + this.property = property; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java new file mode 100644 index 0000000000..e47333457f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; + +public class Service extends Component { + public Service() { + super(new ServiceMetadataDefinition()); + componentType = ComponentTypeEnum.SERVICE; + } + + public Service(ComponentMetadataDefinition serviceMetadataDefinition) { + super(serviceMetadataDefinition); + componentType = ComponentTypeEnum.SERVICE; + } + + private Map serviceApiArtifacts; + + private List additionalInformation; + + public Map getServiceApiArtifacts() { + return serviceApiArtifacts; + } + + public void setServiceApiArtifacts(Map serviceApiArtifacts) { + this.serviceApiArtifacts = serviceApiArtifacts; + } + + public String getProjectCode() { + return getServiceMetadataDefinition().getProjectCode(); + } + + public void setProjectCode(String projectName) { + getServiceMetadataDefinition().setProjectCode(projectName); + } + + public DistributionStatusEnum getDistributionStatus() { + String distributionStatus = getServiceMetadataDefinition().getDistributionStatus(); + if (distributionStatus != null) { + return DistributionStatusEnum.valueOf(distributionStatus); + } else { + return null; + } + } + + public void setDistributionStatus(DistributionStatusEnum distributionStatus) { + if (distributionStatus != null) + getServiceMetadataDefinition().setDistributionStatus(distributionStatus.name()); + } + + private ServiceMetadataDataDefinition getServiceMetadataDefinition() { + return (ServiceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition(); + } + + public List getAdditionalInformation() { + return additionalInformation; + } + + public void setAdditionalInformation(List additionalInformation) { + this.additionalInformation = additionalInformation; + } + + @Override + public String toString() { + return "Service [componentMetadataDefinition=" + getComponentMetadataDefinition() + // + ", resourceInstances=" + resourceInstances + ", + // resourceInstancesRelations=" + resourceInstancesRelations + ", + // resourceInstancesRelations=" + // + resourceInstancesRelations + + " ]"; + } + + @Override + public void setSpecificComponetTypeArtifacts(Map specificComponentTypeArtifacts) { + setServiceApiArtifacts(specificComponentTypeArtifacts); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java new file mode 100644 index 0000000000..21b2e43873 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.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.model; + +import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; + +public class ServiceMetadataDefinition extends ComponentMetadataDefinition { + + public ServiceMetadataDefinition() { + super(); + this.componentMetadataDataDefinition = new ServiceMetadataDataDefinition(); + } + + public ServiceMetadataDefinition(ServiceMetadataDataDefinition component) { + super(component); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java new file mode 100644 index 0000000000..f3edfe2c6c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.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.model; + +public class Tag { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Tag other = (Tag) obj; + if (name == null) { + if (other.getClass() != null) { + return false; + } + } else if (!name.equals(other.getName())) { + return false; + } + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java new file mode 100644 index 0000000000..2e92ca5df3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.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.model; + +import java.io.Serializable; +import java.util.List; + +public class TargetCapabilityRelDef implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -7571489368200736413L; + + private String toNode; + + // private List> relationships; + + private List relationships; + + public TargetCapabilityRelDef() { + super(); + } + + public TargetCapabilityRelDef(String toNode, List relationships) { + super(); + this.toNode = toNode; + this.relationships = relationships; + } + + public String getToNode() { + return toNode; + } + + public void setToNode(String toNode) { + this.toNode = toNode; + } + + // public String getCapabilityOwnerId() { + // return capabilityOwnerId; + // } + // + // public void setCapabilityOwnerId(String capabilityOwnerId) { + // this.capabilityOwnerId = capabilityOwnerId; + // } + + public List getRelationships() { + return relationships; + } + + public void setRelationships(List relationships) { + this.relationships = relationships; + } + + @Override + public String toString() { + return "TargetCapabilityRelDef [ toNode=" + toNode + // + ", capabilityOwnerId=" + capabilityOwnerId + + ", relationships=" + relationships + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java new file mode 100644 index 0000000000..d16330481e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.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.model; + +import java.util.List; + +public class UploadCapInfo extends UploadInfo { + /** + * specify the node type(Optional by tosca) + */ + private List validSourceTypes; + + private List properties; + + private String node; + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + + public List getValidSourceTypes() { + return validSourceTypes; + } + + public void setValidSourceTypes(List validSourceTypes) { + this.validSourceTypes = validSourceTypes; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java new file mode 100644 index 0000000000..329e816ea7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.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.model; + +import java.util.List; +import java.util.Map; + +public class UploadComponentInstanceInfo { + private String name; + private String type; + private Map> capabilities; + private Map> requirements; + private Map> properties; + + public Map> getProperties() { + return properties; + } + + public void setProperties(Map> properties) { + this.properties = properties; + } + + 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 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-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java new file mode 100644 index 0000000000..75707ee77c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.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.model; + +public abstract class UploadInfo { + + private String type; + + private String name; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java new file mode 100644 index 0000000000..60a58c9aed --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.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.model; + +import java.util.List; +import java.util.Map; + +public class UploadPropInfo extends UploadInfo { + + private Object value; + + private String description; + + private boolean password; + + private List get_input; + + public List getGet_input() { + return get_input; + } + + public void setGet_input(List get_input) { + this.get_input = get_input; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isPassword() { + return password; + } + + public void setPassword(boolean password) { + this.password = password; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java new file mode 100644 index 0000000000..7f2834bddf --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.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.model; + +import java.util.Map; + +public class UploadReqInfo extends UploadInfo { + /** + * specify the node type(Optional by tosca) + */ + + private String capabilityName; + + private String node; + + public String getCapabilityName() { + return capabilityName; + } + + public void setCapabilityName(String capabilityName) { + this.capabilityName = capabilityName; + } + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java new file mode 100644 index 0000000000..385b15c728 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java @@ -0,0 +1,304 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.common.api.UploadArtifactInfo; + +public class UploadResourceInfo { + + public UploadResourceInfo(String payload, String payloadName, String description, String category, + List tags, List artifactsList) { + super(); + this.payloadData = payload; + this.payloadName = payloadName; + this.description = description; + // this.category = category; + this.tags = tags; + this.artifactList = artifactsList; + if (category != null) { + String[] arr = category.split("/"); + if (arr.length >= 2) { + categories = new ArrayList<>(); + CategoryDefinition catDef = new CategoryDefinition(); + catDef.setName(arr[0]); + SubCategoryDefinition subCat = new SubCategoryDefinition(); + subCat.setName(arr[1]); + catDef.addSubCategory(subCat); + categories.add(catDef); + } + } + } + + public UploadResourceInfo() { + } + + private String payloadData; + private String payloadName; + private String description; + // private String category; + private List tags; + private List categories; + + private List artifactList; + private String contactId, name, resourceIconPath, icon, vendorName, vendorRelease; + + private String resourceType = "VFC"; + + public String getPayloadData() { + return payloadData; + } + + public void setPayloadData(String payload) { + this.payloadData = payload; + } + + public String getPayloadName() { + return payloadName; + } + + public void setPayloadName(String payloadName) { + this.payloadName = payloadName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + // public String getCategory() { + // return category; + // } + // public void setCategory(String category) { + // this.category = category; + // } + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public List getArtifactList() { + return artifactList; + } + + public void setArtifactList(List artifactsList) { + this.artifactList = artifactsList; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((artifactList == null) ? 0 : artifactList.hashCode()); + result = prime * result + ((contactId == null) ? 0 : contactId.hashCode()); + // result = prime * result + ((category == null) ? 0 : + // category.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((icon == null) ? 0 : icon.hashCode()); + result = prime * result + ((payloadData == null) ? 0 : payloadData.hashCode()); + result = prime * result + ((payloadName == null) ? 0 : payloadName.hashCode()); + result = prime * result + ((resourceIconPath == null) ? 0 : resourceIconPath.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((tags == null) ? 0 : tags.hashCode()); + result = prime * result + ((vendorName == null) ? 0 : vendorName.hashCode()); + result = prime * result + ((vendorRelease == null) ? 0 : vendorRelease.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + UploadResourceInfo other = (UploadResourceInfo) obj; + if (artifactList == null) { + if (other.artifactList != null) + return false; + } else if (!artifactList.equals(other.artifactList)) + return false; + if (contactId == null) { + if (other.contactId != null) + return false; + } else if (!contactId.equals(other.contactId)) + return false; + // if (category == null) { + // if (other.category != null) + // return false; + // } else if (!category.equals(other.category)) + // return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (icon == null) { + if (other.icon != null) + return false; + } else if (!icon.equals(other.icon)) + return false; + if (payloadData == null) { + if (other.payloadData != null) + return false; + } else if (!payloadData.equals(other.payloadData)) + return false; + if (payloadName == null) { + if (other.payloadName != null) + return false; + } else if (!payloadName.equals(other.payloadName)) + return false; + if (resourceIconPath == null) { + if (other.resourceIconPath != null) + return false; + } else if (!resourceIconPath.equals(other.resourceIconPath)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (tags == null) { + if (other.tags != null) + return false; + } else if (!tags.equals(other.tags)) + return false; + if (vendorName == null) { + if (other.vendorName != null) + return false; + } else if (!vendorName.equals(other.vendorName)) + return false; + if (vendorRelease == null) { + if (other.vendorRelease != null) + return false; + } else if (!vendorRelease.equals(other.vendorRelease)) + return false; + return true; + } + + public String getContactId() { + return contactId; + } + + public void setContactId(String userId) { + this.contactId = userId; + } + + public String getName() { + return name; + } + + public void setName(String resourceName) { + this.name = resourceName; + } + + // Icon when using UI import otherwise resourceIconPath + public String getResourceIconPath() { + return (resourceIconPath != null) ? resourceIconPath : icon; + } + + public void setResourceIconPath(String resourceIconPath) { + this.resourceIconPath = resourceIconPath; + } + + 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 void setIcon(String icon) { + this.icon = icon; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public void addSubCategory(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); + } + 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); + } + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java new file mode 100644 index 0000000000..129c35b708 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java @@ -0,0 +1,205 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.openecomp.sdc.be.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.resources.data.UserData; + +public class User { + public static final String FORCE_DELETE_HEADER_FLAG = "FORCE_DELETE"; + + private String firstName; + + private String lastName; + + private String userId; + + private String email; + + private String role; + + private Long lastLoginTime; + + private UserStatusEnum status = UserStatusEnum.ACTIVE; + + public User() { + } + + public User(UserData userDate) { + this(userDate.getFirstName(), userDate.getLastName(), userDate.getUserId(), userDate.getEmail(), + userDate.getRole(), userDate.getLastLoginTime()); + } + + public User(String firstName, String lastName, String userId, String emailAddress, String role, + Long lastLoginTime) { + this.firstName = firstName; + this.lastName = lastName; + this.userId = userId; + this.email = emailAddress; + this.role = role; + this.lastLoginTime = lastLoginTime; + + } + + public void copyData(User other) { + this.firstName = other.getFirstName(); + this.lastName = other.getLastName(); + this.userId = other.getUserId(); + this.email = other.getEmail(); + this.role = other.getRole(); + this.lastLoginTime = other.getLastLoginTime(); + + } + + public User(User aUser) { + this(aUser.getFirstName(), aUser.getLastName(), aUser.getUserId(), aUser.getEmail(), aUser.getRole(), + aUser.getLastLoginTime()); + } + + 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 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 getFullName() { + return this.getFirstName() + " " + this.getLastName(); + } + + public void setLastLoginTime() { + DateTime now = new DateTime(DateTimeZone.UTC); + this.lastLoginTime = now.getMillis(); + } + + public void setLastLoginTime(Long time) { + this.lastLoginTime = time; + } + + public Long getLastLoginTime() { + return this.lastLoginTime; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((userId == null) ? 0 : userId.hashCode()); + result = prime * result + ((email == null) ? 0 : email.hashCode()); + result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); + result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); + result = prime * result + ((role == null) ? 0 : role.hashCode()); + result = prime * result + ((lastLoginTime == null) ? 0 : lastLoginTime.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User) obj; + if (userId == null) { + if (other.userId != null) + return false; + } else if (!userId.equals(other.userId)) + return false; + if (email == null) { + if (other.email != null) + return false; + } else if (!email.equals(other.email)) + return false; + if (firstName == null) { + if (other.firstName != null) + return false; + } else if (!firstName.equals(other.firstName)) + return false; + if (lastName == null) { + if (other.lastName != null) + return false; + } else if (!lastName.equals(other.lastName)) + return false; + if (role == null) { + if (other.role != null) + return false; + } else if (!role.equals(other.role)) + return false; + if (lastLoginTime == null) { + if (other.lastLoginTime != null) + return false; + } else if (!lastLoginTime.equals(other.lastLoginTime)) + return false; + return true; + } + + public UserStatusEnum getStatus() { + return status; + } + + public void setStatus(UserStatusEnum status) { + this.status = status; + } + + @Override + public String toString() { + return "User [firstName=" + firstName + ", lastName=" + lastName + ", userId=" + userId + ", email=" + email + + ", role=" + role + ", last login time=" + lastLoginTime + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java new file mode 100644 index 0000000000..bb8a1b0129 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.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.model.cache; + +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; + +import fj.data.Either; + +public interface ApplicationCache { + + public abstract Either, TitanOperationStatus> getAll(); + + public abstract Either get(String uniqueId); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java new file mode 100644 index 0000000000..31664c929b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java @@ -0,0 +1,335 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.cache; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.apache.commons.lang3.tuple.ImmutablePair; +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.config.Configuration.ApplicationL1CacheConfig; +import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheInfo; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.resources.data.DataTypeData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("application-datatype-cache") +public class ApplicationDataTypeCache implements ApplicationCache, Runnable { + + private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private final Lock r = rwl.readLock(); + private final Lock w = rwl.writeLock(); + + private Map data = new HashMap<>(); + + private ScheduledExecutorService scheduledPollingService = Executors.newScheduledThreadPool(1, + new BasicThreadFactory.Builder().namingPattern("ApplicationDataTypeCacheThread-%d").build()); + ScheduledFuture scheduledFuture = null; + + private static Logger log = LoggerFactory.getLogger(ApplicationDataTypeCache.class.getName()); + + private int firstRunDelayInSec = 30; + private int pollingIntervalInSec = 60; + + @Resource + private PropertyOperation propertyOperation; + + @PostConstruct + public void init() { + + ApplicationL1CacheConfig applicationL1CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL1Cache(); + if (applicationL1CacheConfig != null) { + if (applicationL1CacheConfig.getDatatypes() != null) { + ApplicationL1CacheInfo datatypesInfo = applicationL1CacheConfig.getDatatypes(); + if (datatypesInfo.getEnabled()) { + Integer intervalInSec = datatypesInfo.getPollIntervalInSec(); + if (intervalInSec != null) { + pollingIntervalInSec = intervalInSec; + } + Integer firstRunDelay = datatypesInfo.getFirstRunDelay(); + if (firstRunDelay != null) { + firstRunDelayInSec = firstRunDelay; + } + log.trace("ApplicationDataTypesCache polling interval is " + pollingIntervalInSec + " seconds."); + if (scheduledPollingService != null) { + log.debug("Start ApplicationDataTypeCache polling task. polling interval {} seconds", + pollingIntervalInSec); + scheduledFuture = scheduledPollingService.scheduleAtFixedRate(this, firstRunDelayInSec, + pollingIntervalInSec, TimeUnit.SECONDS); + } + + } + } else { + BeEcompErrorManager.getInstance().logInternalFlowError("ApplicationDataTypesCache", "Cache is disabled", + ErrorSeverity.INFO); + } + } else { + BeEcompErrorManager.getInstance().logInternalFlowError("ApplicationDataTypesCache", "Cache is disabled", + ErrorSeverity.INFO); + } + + } + + @PreDestroy + void destroy() { + + if (scheduledFuture != null) { + boolean result = scheduledFuture.cancel(true); + log.debug("Stop polling task. result = {}", result); + + scheduledFuture = null; + } + shutdownExecutor(); + } + + 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)) + log.debug("Pool did not terminate"); + } + } catch (InterruptedException ie) { + // (Re-)Cancel if current thread also interrupted + scheduledPollingService.shutdownNow(); + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + } + + private Either, TitanOperationStatus> getAllDataTypesFromGraph() { + + Either, TitanOperationStatus> allDataTypes = propertyOperation + .getAllDataTypes(); + + return allDataTypes; + + } + + @Override + public Either, TitanOperationStatus> getAll() { + + try { + + r.lock(); + if (data == null || data.isEmpty()) { + return getAllDataTypesFromGraph(); + } + + return Either.left(data); + + } finally { + r.unlock(); + } + } + + @Override + public Either get(String uniqueId) { + + try { + r.lock(); + + if (data == null || data.isEmpty()) { + Either dataTypeByUid = propertyOperation + .getDataTypeByUid(uniqueId); + return dataTypeByUid; + } else { + DataTypeDefinition dataTypeDefinition = data.values().stream() + .filter(p -> p.getUniqueId().equals(uniqueId)).findFirst().orElse(null); + if (dataTypeDefinition == null) { + Either dataTypeByUid = propertyOperation + .getDataTypeByUid(uniqueId); + return dataTypeByUid; + } else { + return Either.left(dataTypeDefinition); + } + } + } finally { + r.unlock(); + } + } + + @Override + public void run() { + log.trace("run() method. polling db to fetch data types"); + + try { + + Long start = System.currentTimeMillis(); + log.trace("Start fetching all data types from db"); + Either, TitanOperationStatus> allDataTypeNodes = propertyOperation.getAllDataTypeNodes(); + Long end = System.currentTimeMillis(); + log.trace("Finish fetching all data types from db. Took " + (end - start) + " Milliseconds"); + if (allDataTypeNodes.isRight()) { + TitanOperationStatus status = allDataTypeNodes.right().value(); + if (status != TitanOperationStatus.OK) { + log.debug("ApplicationDataTypesCache - Failed to fetch all data types nodes"); + BeEcompErrorManager.getInstance().logInternalConnectionError("FetchDataTypes", + "Failed to fetch data types from graph(cache)", ErrorSeverity.INFO); + } + } else { + + List list = allDataTypeNodes.left().value(); + if (list != null) { + + Map> dataTypeNameToModificationTime = list.stream() + .collect(Collectors.toMap(p -> p.getDataTypeDataDefinition().getName(), + p -> new ImmutablePair(p.getDataTypeDataDefinition().getCreationTime(), + p.getDataTypeDataDefinition().getModificationTime()))); + + Map> currentDataTypeToModificationTime = new HashMap<>(); + try { + r.lock(); + if (data != null) { + currentDataTypeToModificationTime = data.values().stream().collect(Collectors.toMap( + p -> p.getName(), + p -> new ImmutablePair(p.getCreationTime(), p.getModificationTime()))); + + } + } finally { + r.unlock(); + } + + boolean isChanged = compareDataTypes(dataTypeNameToModificationTime, + currentDataTypeToModificationTime); + if (isChanged) { + replaceAllData(); + } + + } + } + + } catch (Exception e) { + log.debug("unexpected error occured", e); + + BeEcompErrorManager.getInstance().logInternalUnexpectedError("ApplicationDataTypesCache", + "Failed to run refresh data types job", ErrorSeverity.INFO); + } finally { + try { + propertyOperation.getTitanGenericDao().commit(); + } catch (Exception e) { + log.trace("Failed to commit ApplicationDataTypeCache", e); + } + } + + } + + private boolean compareDataTypes(Map> dataTypeNameToModificationTime, + Map> currentDataTypeToModificationTime) { + if (dataTypeNameToModificationTime.size() != currentDataTypeToModificationTime.size()) { + return true; + } else { + + Set currentkeySet = currentDataTypeToModificationTime.keySet(); + Set keySet = dataTypeNameToModificationTime.keySet(); + + if (currentkeySet.containsAll(keySet)) { + + for (Entry> entry : dataTypeNameToModificationTime.entrySet()) { + String dataTypeName = entry.getKey(); + ImmutablePair creationAndModificationTimes = entry.getValue(); + long creationTime = creationAndModificationTimes.getLeft() == null ? 0 + : creationAndModificationTimes.getLeft().longValue(); + long modificationTime = creationAndModificationTimes.getRight() == null ? 0 + : creationAndModificationTimes.getRight().longValue(); + + ImmutablePair currentEntry = currentDataTypeToModificationTime.get(dataTypeName); + long currentCreationTime = currentEntry.getLeft() == null ? 0 : currentEntry.getLeft().longValue(); + long currentModificationTime = currentEntry.getRight() == null ? 0 + : currentEntry.getRight().longValue(); + + if (creationTime > currentCreationTime || modificationTime > currentModificationTime) { + log.debug("Datatype {} was updated. Creation Time {} vs {}. Modification Time {} vs {}", + dataTypeName, currentCreationTime, creationTime, currentModificationTime, + modificationTime); + return true; + } + } + } else { + return true; + } + + } + + return false; + } + + private void replaceAllData() { + + Either, TitanOperationStatus> allDataTypes = propertyOperation + .getAllDataTypes(); + + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Failed to fetch all data types from db. Status is {}", status); + } else { + + try { + w.lock(); + + Map newDataTypes = allDataTypes.left().value(); + data = newDataTypes; + + BeEcompErrorManager.getInstance().logInternalFlowError("ReplaceDataTypesCache", + "Succeed to replace the data types cache", ErrorSeverity.INFO); + + } finally { + w.unlock(); + } + + } + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java new file mode 100644 index 0000000000..6732adbdb1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java @@ -0,0 +1,997 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.cache; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +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.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheCatalogInfo; +import org.openecomp.sdc.be.config.Configuration.ApplicationL2CacheConfig; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.cassandra.ComponentCassandraDao; +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.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +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.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.*; +import org.openecomp.sdc.be.resources.data.ComponentCacheData; +import org.openecomp.sdc.common.util.SerializationUtils; +import org.openecomp.sdc.common.util.ZipUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("component-cache") +public class ComponentCache { + + private static Logger logger = LoggerFactory.getLogger(ComponentCache.class.getName()); + + @javax.annotation.Resource + ComponentCassandraDao componentCassandraDao; + + @javax.annotation.Resource + ResourceOperation resourceOperation; + + @javax.annotation.Resource + ServiceOperation serviceOperation; + + @javax.annotation.Resource + ProductOperation productOperation; + + private Map> catalogInMemoryCache = new HashMap<>(); + private final ReentrantReadWriteLock rwCatalogLock = new ReentrantReadWriteLock(); + private final Lock rCatalogLock = rwCatalogLock.readLock(); + private final Lock wCatalogLock = rwCatalogLock.writeLock(); + + boolean enabled = true; + int catalogInMemorySizePerResource = 300; + int catalogInMemorySizePerService = 200; + int catalogInMemorySizePerProduct = 100; + boolean catalogInMemoryEnabled = true; + Map limitMemoryCatalogSizePerType = new HashMap<>(); + + @PostConstruct + public void init() { + + Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration(); + if (configuration != null) { + ApplicationL2CacheConfig applicationL2Cache = configuration.getApplicationL2Cache(); + if (applicationL2Cache != null) { + boolean isEnabled = applicationL2Cache.isEnabled(); + this.enabled = isEnabled; + + ApplicationL1CacheCatalogInfo catalog = applicationL2Cache.getCatalogL1Cache(); + if (catalog != null) { + catalogInMemoryEnabled = catalog.getEnabled(); + catalogInMemorySizePerResource = catalog.getResourcesSizeInCache(); + catalogInMemorySizePerService = catalog.getServicesSizeInCache(); + catalogInMemorySizePerProduct = catalog.getProductsSizeInCache(); + } + } + } + + ComponentTypeEnum[] typesForCache = { ComponentTypeEnum.RESOURCE, ComponentTypeEnum.SERVICE, + ComponentTypeEnum.PRODUCT }; + for (ComponentTypeEnum typeEnum : typesForCache) { + Map map = new HashMap<>(); + catalogInMemoryCache.put(typeEnum, map); + } + + limitMemoryCatalogSizePerType.put(ComponentTypeEnum.RESOURCE, catalogInMemorySizePerResource); + limitMemoryCatalogSizePerType.put(ComponentTypeEnum.SERVICE, catalogInMemorySizePerService); + limitMemoryCatalogSizePerType.put(ComponentTypeEnum.PRODUCT, catalogInMemorySizePerProduct); + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Either getComponent(String componentUid, Long lastModificationTime, + Function filterFieldsFunc) { + + Either, ActionStatus> componentFromCache = getComponentFromCache( + componentUid, lastModificationTime, filterFieldsFunc); + + if (componentFromCache.isRight()) { + return Either.right(componentFromCache.right().value()); + } + + return Either.left(componentFromCache.left().value().left); + + } + + public Either, ActionStatus> getAllComponentIdTimeAndType() { + if (false == isEnabled()) { + return Either.right(ActionStatus.NOT_ALLOWED); + } + + Either, ActionStatus> componentRes = componentCassandraDao + .getAllComponentIdTimeAndType(); + + return componentRes; + + } + + /** + * get components for catalog + * + * @param components + * @param componentTypeEnum + * @return + */ + @Deprecated + public Either, List, Set>, ActionStatus> getComponentsForCatalog( + Set components, ComponentTypeEnum componentTypeEnum) { + + if (false == isEnabled()) { + logger.debug("In getComponentsForCatalog for type {}. Cache is disabled.", + componentTypeEnum.name().toLowerCase()); + return Either.right(ActionStatus.NOT_ALLOWED); + } + logger.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase()); + + Function, List> filterFieldsFunc = x -> filterForCatalog(x); + + Set leftComponentsForSearch = new HashSet<>(); + leftComponentsForSearch.addAll(components); + + // get components from inmemory cache + List componentsFromMemory = null; + if (true == catalogInMemoryEnabled) { + componentsFromMemory = getDataFromInMemoryCache(components, componentTypeEnum); + logger.debug("The number of components of type {} fetched from memory is {}", + componentTypeEnum.name().toLowerCase(), + componentsFromMemory == null ? 0 : componentsFromMemory.size()); + if (componentsFromMemory != null) { + componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId())); + } + } else { + logger.debug("Catalog InMemory cache is disabled"); + } + + logger.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(), + leftComponentsForSearch.size()); + + // get components from cassandra cache and filter each component + Either, List, Set>, ActionStatus> result = getComponents( + leftComponentsForSearch, filterFieldsFunc); + + if (result.isLeft()) { + // add inmemory components to the valid components(not dirty) + List foundComponents = result.left().value().getLeft(); + if (componentsFromMemory != null) { + foundComponents.addAll(componentsFromMemory); + } + if (true == catalogInMemoryEnabled) { + updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum); + } + } + + return result; + } + + /** + * @param foundComponents + * @param componentTypeEnum + */ + private void updateCatalogInMemoryCacheWithCertified(List foundComponents, + ComponentTypeEnum componentTypeEnum) { + + try { + wCatalogLock.lock(); + + long start = System.currentTimeMillis(); + Map map = catalogInMemoryCache.get(componentTypeEnum); + int mapSizeBefore = map.size(); + map.clear(); + Map collect = foundComponents.stream() + .filter(p -> p.getLifecycleState() == LifecycleStateEnum.CERTIFIED) + .limit(limitMemoryCatalogSizePerType.get(componentTypeEnum)) + .collect(Collectors.toMap(p -> p.getUniqueId(), p -> p)); + map.putAll(collect); + logger.debug( + "Size of in memory cache for catalog {}(certified only): Before {}, After {}. Replacement Time is {} ms.", + componentTypeEnum.name().toLowerCase(), mapSizeBefore, map.size(), + System.currentTimeMillis() - start); + } finally { + wCatalogLock.unlock(); + } + + } + + private List getDataFromInMemoryCache(Set components, ComponentTypeEnum componentTypeEnum) { + List foundComponents = new ArrayList<>(); + + try { + + rCatalogLock.lock(); + + Map map = catalogInMemoryCache.get(componentTypeEnum); + for (String compUid : components) { + Component component = map.get(compUid); + if (component != null) { + foundComponents.add(component); + } + } + + } finally { + rCatalogLock.unlock(); + } + + return foundComponents; + } + + /** + * + * get full components from cassandra. On each component apply filter + * function in order to remove unused members + * + * @param components + * @param filterFieldsFunc + * @return or Error + */ + public Either, List, Set>, ActionStatus> getComponents( + Set components, Function, List> filterFieldsFunc) { + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return Either.right(ActionStatus.NOT_ALLOWED); + } + + Either, List, Set>, ActionStatus> componentsFull = getComponentsFull( + components); + + if (componentsFull.isRight()) { + return Either.right(componentsFull.right().value()); + } + + ImmutableTriple, List, Set> immutableTriple = componentsFull.left().value(); + List foundResources = immutableTriple.left; + List foundDirtyResources = immutableTriple.middle; + Set notFoundResources = immutableTriple.right; + + List filterdFoundResources = filterFieldsFunc.apply(foundResources); + List filterdFoundDirtyResources = filterFieldsFunc.apply(foundDirtyResources); + + ImmutableTriple, List, Set> result = new ImmutableTriple, List, Set>( + filterdFoundResources, filterdFoundDirtyResources, notFoundResources); + + return Either.left(result); + + } + + public Either, List, Set>, ActionStatus> getComponentsForLeftPanel( + ComponentTypeEnum componentTypeEnum, String internalComponentType, Set filteredResources) { + + logger.debug("In getComponentsForLeftPanel componentTypeEnum = {}, internalComponentType = {}", + componentTypeEnum, internalComponentType); + + Function, List> filterFieldsFunc = x -> filterForLeftPanel(x); + + return getComponents(filteredResources, filterFieldsFunc); + + } + + private List filterForLeftPanel(List components) { + + List result = new ArrayList<>(); + if (components != null) { + components.forEach(p -> result.add(filterFieldsForLeftPanel(p))); + } + + return result; + } + + private List filterForCatalog(List components) { + + List result = new ArrayList<>(); + if (components != null) { + components.forEach(p -> result.add(filterFieldsForCatalog(p))); + } + + return result; + } + + private Component filterFieldsForLeftPanel(Component component) { + + Component result = null; + ComponentTypeEnum componentTypeEnum = component.getComponentType(); + switch (componentTypeEnum) { + case RESOURCE: + result = new Resource(); + copyFieldsForLeftPanel(component, result); + break; + case SERVICE: + result = new Service(); + copyFieldsForLeftPanel(component, result); + break; + default: + break; + } + + return result; + } + + private Component filterFieldsForCatalog(Component component) { + + Component result = null; + ComponentTypeEnum componentTypeEnum = component.getComponentType(); + switch (componentTypeEnum) { + case RESOURCE: + result = new Resource(); + copyFieldsForCatalog(component, result); + break; + case SERVICE: + result = new Service(); + copyFieldsForCatalog(component, result); + break; + case PRODUCT: + result = new Product(); + copyFieldsForCatalog(component, result); + default: + break; + } + + return result; + } + + /** + * Copy relevant fields to the filtered component for left panel + * + * @param component + * @param filteredComponent + */ + private void copyFieldsForLeftPanel(Component component, Component filteredComponent) { + + ComponentTypeEnum componentTypeEnum = component.getComponentType(); + filteredComponent.setCategories(component.getCategories()); + filteredComponent.setComponentType(component.getComponentType()); + if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType()) + && ResourceTypeEnum.VL.equals(((ResourceMetadataDataDefinition) component + .getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType())) { + filteredComponent.setCapabilities(component.getCapabilities()); + filteredComponent.setRequirements(component.getRequirements()); + } + filteredComponent.setVersion(component.getVersion()); + filteredComponent.setDescription(component.getDescription()); + filteredComponent.setUniqueId(component.getUniqueId()); + filteredComponent.setIcon(component.getIcon()); + filteredComponent.setTags(component.getTags()); + // filteredComponent.setAllVersions(component.getAllVersions()); + filteredComponent.setLifecycleState(component.getLifecycleState()); + // filteredComponent.setHighestVersion(component.isHighestVersion()); + filteredComponent.setInvariantUUID(component.getInvariantUUID()); + filteredComponent.setUUID(component.getUUID()); + filteredComponent.setSystemName(component.getSystemName()); + filteredComponent.setName(component.getName()); + + if (componentTypeEnum == ComponentTypeEnum.RESOURCE) { + Resource resource = (Resource) component; + Resource filteredResource = (Resource) filteredComponent; + filteredResource.setToscaResourceName(resource.getToscaResourceName()); + // filteredResource.setAbstract(resource.isAbstract()); + // filteredResource.setVendorName(resource.getVendorName()); + // filteredResource.setVendorRelease(resource.getVendorRelease()); + filteredResource.setResourceType(resource.getResourceType()); + } else if (componentTypeEnum == ComponentTypeEnum.SERVICE) { + // Service service = (Service)component; + // Service filteredService = (Service)filteredComponent; + // filteredService.setDistributionStatus(service.getDistributionStatus()); + } + } + + private void copyFieldsForCatalog(Component component, Component filteredComponent) { + + ComponentTypeEnum componentTypeEnum = component.getComponentType(); + filteredComponent.setCategories(component.getCategories()); + filteredComponent.setComponentType(component.getComponentType()); + filteredComponent.setVersion(component.getVersion()); + filteredComponent.setDescription(component.getDescription()); + filteredComponent.setUniqueId(component.getUniqueId()); + filteredComponent.setIcon(component.getIcon()); + filteredComponent.setTags(component.getTags()); + // filteredComponent.setAllVersions(component.getAllVersions()); + filteredComponent.setLifecycleState(component.getLifecycleState()); + // filteredComponent.setHighestVersion(component.isHighestVersion()); + // filteredComponent.setInvariantUUID(component.getInvariantUUID()); + filteredComponent.setSystemName(component.getSystemName()); + filteredComponent.setName(component.getName()); + filteredComponent.setLastUpdateDate(component.getLastUpdateDate()); + + if (componentTypeEnum == ComponentTypeEnum.RESOURCE) { + Resource resource = (Resource) component; + Resource filteredResource = (Resource) filteredComponent; + filteredResource.setToscaResourceName(resource.getToscaResourceName()); + // filteredResource.setAbstract(resource.isAbstract()); + // filteredResource.setVendorName(resource.getVendorName()); + // filteredResource.setVendorRelease(resource.getVendorRelease()); + filteredResource.setResourceType(resource.getResourceType()); + } else if (componentTypeEnum == ComponentTypeEnum.SERVICE) { + Service service = (Service) component; + Service filteredService = (Service) filteredComponent; + filteredService.setDistributionStatus(service.getDistributionStatus()); + } + } + + /** + * get components from cache of a given list ou unique ids. + * + * for each component data from cassandra, unzip the data if needed and + * deserialize the unzipped data to java object(Component). + * + * @param filteredResources + * @return ImmutableTripple or ActionStatus. | |-- components |-- dirty + * components - components with dirty flag = true. |-- set of non + * cached components + * + */ + private Either, List, Set>, ActionStatus> getComponentsFull( + Set filteredResources) { + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return Either.right(ActionStatus.NOT_ALLOWED); + } + + List foundResources = new LinkedList<>(); + List foundDirtyResources = new LinkedList<>(); + Set notFoundResources = new HashSet<>(); + ImmutableTriple, List, Set> result = new ImmutableTriple, List, Set>( + foundResources, foundDirtyResources, notFoundResources); + + long cassandraFetchStart = System.currentTimeMillis(); + List uidsList = new ArrayList<>(); + uidsList.addAll(filteredResources); + Either, ActionStatus> componentsFromCache = componentCassandraDao + .getComponents(uidsList); + + long cassandraFetchEnd = System.currentTimeMillis(); + logger.debug("Fetch time from cassandara of all components took {} ms", + (cassandraFetchEnd - cassandraFetchStart)); + if (componentsFromCache.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache", + "Failed to fetch components from cache", ErrorSeverity.ERROR); + return Either.right(componentsFromCache.right().value()); + } + + List list = componentsFromCache.left().value(); + logger.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size())); + if (list != null && false == list.isEmpty()) { + + List filteredData = list.stream().filter(p -> filteredResources.contains(p.getId())) + .collect(Collectors.toList()); + logger.debug("Number of components filterd is {}", filteredData == null ? 0 : filteredData.size()); + + if (filteredData != null) { + long desStart = System.currentTimeMillis(); + + for (ComponentCacheData componentCacheData : filteredData) { + + logger.debug("Process uid {} from cache", componentCacheData.getId()); + + String compUid = componentCacheData.getId(); + + Either deserializeExt = convertComponentCacheToComponent( + componentCacheData); + + if (deserializeExt.isLeft()) { + Component component = deserializeExt.left().value(); + if (false == componentCacheData.getIsDirty()) { + foundResources.add(component); + } else { + foundDirtyResources.add(component); + } + } else { + notFoundResources.add(compUid); + } + + } + long desEnd = System.currentTimeMillis(); + logger.debug("Deserialization and unzip of {} components took {} ms", filteredData.size(), + (desEnd - desStart)); + } + } + List foundResourcesUid = foundResources.stream().map(p -> p.getUniqueId()).collect(Collectors.toList()); + List foundDirtyResourcesUid = foundDirtyResources.stream().map(p -> p.getUniqueId()) + .collect(Collectors.toList()); + logger.debug("Number of processed components from cache is {}", + (foundResourcesUid.size() + foundDirtyResourcesUid.size())); + Set notCachedResources = filteredResources.stream() + .filter(p -> false == foundResourcesUid.contains(p) && false == foundDirtyResourcesUid.contains(p)) + .collect(Collectors.toSet()); + notFoundResources.addAll(notCachedResources); + + if (logger.isDebugEnabled()) { + logger.debug("Number of components fetched is {}", foundResources.size()); + logger.debug("Number of components fetched dirty is {}", foundDirtyResources.size()); + logger.debug("Number of components non cached is {}", notCachedResources.size()); + } + + return Either.left(result); + } + + private Either convertComponentCacheToComponent( + ComponentCacheData componentCacheData) { + + String compUid = componentCacheData.getId(); + + byte[] dataAsArray = componentCacheData.getDataAsArray(); + + if (true == componentCacheData.getIsZipped()) { + long startUnzip = System.nanoTime(); + dataAsArray = ZipUtil.unzip(dataAsArray); + long endUnzip = System.nanoTime(); + logger.trace("Unzip component {} took {} microsecond", compUid, (endUnzip - startUnzip) / 1000); + } + + long startDes = System.nanoTime(); + + Either deserializeExt = deserializeComponent(componentCacheData, dataAsArray); + + long endDes = System.nanoTime(); + logger.trace("Deserialize component {} took {} microsecond", compUid, (endDes - startDes) / 1000); + return deserializeExt; + } + + private Either deserializeComponent(ComponentCacheData componentCacheData, + byte[] dataAsArray) { + String type = componentCacheData.getType(); + NodeTypeEnum typeEnum = NodeTypeEnum.getByNameIgnoreCase(type); + + Either deserializeExt = Either.right(false); + switch (typeEnum) { + case Resource: + deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Resource.class, componentCacheData.getId()); + break; + case Service: + deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Service.class, componentCacheData.getId()); + break; + case Product: + deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Product.class, componentCacheData.getId()); + break; + default: + break; + } + return deserializeExt; + } + + public Either getComponent(String componentUid) { + + return getComponent(componentUid, null, Function.identity()); + + } + + public Either getComponent(String componentUid, Long lastModificationTime) { + + return getComponent(componentUid, lastModificationTime, Function.identity()); + + } + + public boolean setComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum) { + + boolean result = false; + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return false; + } + + ComponentOperation componentOperation = getComponentOperation(nodeTypeEnum); + + if (componentOperation == null) { + return false; + } + + Either either = componentOperation.getComponent(componentUid, false); + if (either.isLeft()) { + Component component = either.left().value(); + result = saveComponent(componentUid, lastModificationTime, nodeTypeEnum, component); + } else { + logger.debug("Failed to get component {} of type {} from graph. Status is {}", componentUid, + nodeTypeEnum.name().toLowerCase(), either.right().value()); + } + + return result; + + } + + private boolean saveComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum, + Component component) { + + logger.trace("Going to save component {} of type {} in cache", componentUid, nodeTypeEnum.name().toLowerCase()); + + boolean result = false; + + Either serializeExt = SerializationUtils.serializeExt(component); + if (serializeExt.isLeft()) { + byte[] serializedData = serializeExt.left().value(); + byte[] zipBytes; + try { + zipBytes = ZipUtil.zipBytes(serializedData); + ComponentCacheData componentCacheData = new ComponentCacheData(); + componentCacheData.setDataAsArray(zipBytes); + componentCacheData.setIsZipped(true); + componentCacheData.setId(componentUid); + componentCacheData.setModificationTime(new Date(lastModificationTime)); + componentCacheData.setType(component.getComponentType().name().toLowerCase()); + + CassandraOperationStatus status = componentCassandraDao.saveComponent(componentCacheData); + + if (status == CassandraOperationStatus.OK) { + result = true; + } + + } catch (IOException e) { + logger.debug("Failed to prepare component {} of type {} for cache", componentUid, + nodeTypeEnum.name().toLowerCase()); + if (logger.isTraceEnabled()) { + logger.trace("Failed to prepare component " + componentUid + " of type " + + nodeTypeEnum.name().toLowerCase() + " for cache"); + } + } + } else { + logger.debug("Failed to serialize component {} of type {} for cache", componentUid, + nodeTypeEnum.name().toLowerCase()); + } + return result; + } + + public boolean setComponent(Component component, NodeTypeEnum nodeTypeEnum) { + + boolean result = false; + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return false; + } + + String componentUid = component.getUniqueId(); + Long lastUpdateDate = component.getLastUpdateDate(); + + result = saveComponent(componentUid, lastUpdateDate, nodeTypeEnum, component); + + return result; + + } + + private ComponentOperation getComponentOperation(NodeTypeEnum nodeTypeEnum) { + ComponentOperation componentOperation = null; + switch (nodeTypeEnum) { + case Resource: + componentOperation = resourceOperation; + break; + case Service: + componentOperation = serviceOperation; + break; + case Product: + componentOperation = productOperation; + break; + default: + break; + } + return componentOperation; + } + + /** + * get components from cache of a given list ou unique ids. + * + * for each component data from cassandra, unzip the data if needed and + * deserialize the unzipped data to java object(Component). + * + * @param filteredResources + * @return ImmutableTripple or ActionStatus. | |-- components |-- set of non + * cached components + * + */ + private Either, Set>, ActionStatus> getComponentsFull( + Map filteredResources) { + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return Either.right(ActionStatus.NOT_ALLOWED); + } + + List foundResources = new LinkedList<>(); + Set notFoundResources = new HashSet<>(); + ImmutablePair, Set> result = new ImmutablePair, Set>( + foundResources, notFoundResources); + + long cassandraFetchStart = System.currentTimeMillis(); + + Either, Set>, ActionStatus> componentsFromCache = componentCassandraDao + .getComponents(filteredResources); + + long cassandraFetchEnd = System.currentTimeMillis(); + logger.debug("Fetch time from cassandara of all components took {} ms", + (cassandraFetchEnd - cassandraFetchStart)); + if (componentsFromCache.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache", + "Failed to fetch components from cache", ErrorSeverity.ERROR); + return Either.right(componentsFromCache.right().value()); + } + + ImmutablePair, Set> immutablePair = componentsFromCache.left().value(); + List list = immutablePair.getLeft(); + logger.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size())); + if (list != null && false == list.isEmpty()) { + + // List filteredData = list.stream().filter(p -> + // filteredResources.contains(p.getId())).collect(Collectors.toList()); + logger.debug("Number of components filterd is {}", list == null ? 0 : list.size()); + + if (list != null) { + long desStart = System.currentTimeMillis(); + + for (ComponentCacheData componentCacheData : list) { + + logger.debug("Process uid {} from cache", componentCacheData.getId()); + + String compUid = componentCacheData.getId(); + + Either deserializeExt = convertComponentCacheToComponent( + componentCacheData); + + if (deserializeExt.isLeft()) { + Component component = deserializeExt.left().value(); + foundResources.add(component); + } else { + notFoundResources.add(compUid); + } + + } + long desEnd = System.currentTimeMillis(); + logger.debug("Deserialization and unzip of {} components took {} ms", list.size(), (desEnd - desStart)); + } + } + logger.debug("Number of processed components from cache is {}", foundResources.size()); + + Set notFoundInCache = immutablePair.getRight(); + notFoundResources.addAll(notFoundInCache); + + if (logger.isDebugEnabled()) { + logger.debug("Number of components fetched is {}", foundResources.size()); + logger.debug("Number of components non cached is {}", notFoundResources.size()); + } + + return Either.left(result); + } + + /** + * get components for catalog + * + * @param components + * @param componentTypeEnum + * @return + */ + public Either, Set>, ActionStatus> getComponentsForCatalog( + Map components, ComponentTypeEnum componentTypeEnum) { + + if (false == isEnabled()) { + logger.debug("In getComponentsForCatalog for type {}. Cache is disabled.", + componentTypeEnum.name().toLowerCase()); + return Either.right(ActionStatus.NOT_ALLOWED); + } + logger.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase()); + + Function, List> filterFieldsFunc = x -> filterForCatalog(x); + + Map leftComponentsForSearch = new HashMap<>(); + leftComponentsForSearch.putAll(components); + + // get components from inmemory cache + List componentsFromMemory = null; + if (true == catalogInMemoryEnabled) { + componentsFromMemory = getDataFromInMemoryCache(components.keySet(), componentTypeEnum); + logger.debug("The number of components of type {} fetched from memory is {}", + componentTypeEnum.name().toLowerCase(), + componentsFromMemory == null ? 0 : componentsFromMemory.size()); + if (componentsFromMemory != null) { + List ignoredComponents = new ArrayList<>(); + for (Component componentFromMem : componentsFromMemory) { + if (componentFromMem.getLastUpdateDate().longValue() != components + .get(componentFromMem.getUniqueId()).longValue()) { + // Ignore the component from memory + ignoredComponents.add(componentFromMem.getUniqueId()); + } + } + + logger.debug("Number of components from type {} ignored from memory cache is {}", + componentTypeEnum.name().toLowerCase(), ignoredComponents.size()); + // remove from memory result the components which are not valid + componentsFromMemory = componentsFromMemory.stream() + .filter(p -> false == ignoredComponents.contains(p.getUniqueId())).collect(Collectors.toList()); + // Remove from leftComponentsForSearch the valid components from + // memory + componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId())); + + } + } else { + logger.debug("Catalog InMemory cache is disabled"); + } + + logger.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(), + leftComponentsForSearch.size()); + + // get components from cassandra cache and filter each component + Either, Set>, ActionStatus> result = getComponents( + leftComponentsForSearch, filterFieldsFunc); + + if (result.isLeft()) { + // add inmemory components to the valid components(not dirty) + List foundComponents = result.left().value().getLeft(); + if (componentsFromMemory != null) { + foundComponents.addAll(componentsFromMemory); + } + if (true == catalogInMemoryEnabled) { + updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum); + } + } + + return result; + } + + /** + * @param components + * - Map of + * @param filterFieldsFunc + * @return + */ + public Either, Set>, ActionStatus> getComponents(Map components, + Function, List> filterFieldsFunc) { + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return Either.right(ActionStatus.NOT_ALLOWED); + } + + Either, Set>, ActionStatus> componentsFull = getComponentsFull( + components); + + if (componentsFull.isRight()) { + return Either.right(componentsFull.right().value()); + } + + ImmutablePair, Set> immutablePair = componentsFull.left().value(); + List foundResources = immutablePair.left; + Set notFoundResources = immutablePair.right; + + List filterdFoundResources = filterFieldsFunc.apply(foundResources); + + ImmutablePair, Set> result = new ImmutablePair, Set>( + filterdFoundResources, notFoundResources); + + return Either.left(result); + + } + + /** + * get the component and its modification time from cache + * + * @param componentUid + * @param filterFieldsFunc + * @return + */ + public Either, ActionStatus> getComponentAndTime(String componentUid, + Function filterFieldsFunc) { + + Either, ActionStatus> componentFromCache = getComponentFromCache( + componentUid, null, filterFieldsFunc); + + if (componentFromCache.isRight()) { + return Either.right(componentFromCache.right().value()); + } + + ImmutablePair immutablePair = componentFromCache.left().value(); + + ImmutablePair result = new ImmutablePair(immutablePair.left, + immutablePair.right.getModificationTime().getTime()); + + return Either.left(result); + } + + private Either, ActionStatus> getComponentFromCache( + String componentUid, Long lastModificationTime, Function filterFieldsFunc) { + if (false == isEnabled()) { + return Either.right(ActionStatus.NOT_ALLOWED); + } + + Either componentRes = componentCassandraDao.getComponent(componentUid); + + if (componentRes.isRight()) { + return Either.right(componentRes.right().value()); + } + + ComponentCacheData componentCacheData = componentRes.left().value(); + + if (lastModificationTime != null) { + long cacheCompModificationTime = componentCacheData.getModificationTime().getTime(); + if (lastModificationTime != cacheCompModificationTime) { + logger.debug( + "Component {} found in cache but its modification time {} does not match to the timestamp in cache {}.", + componentUid, lastModificationTime, cacheCompModificationTime); + return Either.right(ActionStatus.INVALID_CONTENT); + } + } + + Either convertRes = convertComponentCacheToComponent(componentCacheData); + if (convertRes.isRight()) { + return Either.right(ActionStatus.CONVERT_COMPONENT_ERROR); + } + + Component component = convertRes.left().value(); + + Component filteredComponent = component; + if (filterFieldsFunc != null) { + filteredComponent = filterFieldsFunc.apply(component); + } + + ImmutablePair result = new ImmutablePair( + filteredComponent, componentCacheData); + + return Either.left(result); + } + + public ActionStatus deleteComponentFromCache(String id) { + if (false == isEnabled()) { + return ActionStatus.NOT_ALLOWED; + } + CassandraOperationStatus status = this.componentCassandraDao.deleteComponent(id); + if (CassandraOperationStatus.OK.equals(status)) { + return ActionStatus.OK; + } else { + logger.debug("delete component failed with error {}", status); + return ActionStatus.GENERAL_ERROR; + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java new file mode 100644 index 0000000000..bc63b34fec --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.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.be.model.cache; + +import org.openecomp.sdc.be.model.operations.api.IProductOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; + +public class DaoInfo { + private IResourceOperation iResourceOperation; + private IServiceOperation iServiceOperation; + private IProductOperation iProductOperation; + private ComponentCache ComponentCache; + + public DaoInfo(IResourceOperation iResourceOperation, IServiceOperation iServiceOperation, + IProductOperation iProductOperation, org.openecomp.sdc.be.model.cache.ComponentCache componentCache) { + this.iResourceOperation = iResourceOperation; + this.iServiceOperation = iServiceOperation; + this.iProductOperation = iProductOperation; + ComponentCache = componentCache; + } + + public IResourceOperation getResourceOperation() { + return iResourceOperation; + } + + public IServiceOperation getServiceOperation() { + return iServiceOperation; + } + + public IProductOperation getProductOperation() { + return iProductOperation; + } + + public org.openecomp.sdc.be.model.cache.ComponentCache getComponentCache() { + return ComponentCache; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java new file mode 100644 index 0000000000..93249c914a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.cache.jobs; + +import fj.data.Either; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.Function; + +/** + * Created by mlando on 9/7/2016. + */ +public class CheckAndUpdateJob extends Job { + private static Logger log = LoggerFactory.getLogger(CheckAndUpdateJob.class.getName()); + + public CheckAndUpdateJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) { + super(daoInfo, componentId, nodeTypeEnum, timestamp); + } + + @Override + public Object doWork() { + log.trace("starting work on job."); + log.trace("update cache for componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, nodeTypeEnum, + timestamp); + + try { + + // get from cache + Either, ActionStatus> cacheResult = daoInfo.getComponentCache() + .getComponentAndTime(componentId, Function.identity()); + // if error while getting from cache abort and update + if (cacheResult.isRight()) { + // genral error + if (!ActionStatus.RESOURCE_NOT_FOUND.equals(cacheResult.right().value()) + && !ActionStatus.INVALID_CONTENT.equals(cacheResult.right().value())) { + log.debug("failed to get component:{} from cache error:{}", componentId, + cacheResult.right().value()); + return false; + } + // component not in cache put there + else { + return updateCache(componentId, nodeTypeEnum, timestamp); + } + } + ImmutablePair recored = cacheResult.left().value(); + // the cache has allready been updated exit + if (this.timestamp < recored.getRight()) { + log.debug("job timestemp:{} is smaller then the cache timestamp:{} no update is needed.", + this.timestamp, recored.getRight()); + return false; + } + return updateCache(componentId, nodeTypeEnum, timestamp); + + } catch (Exception e) { + log.debug("an exception was encountered during CheckAndUpdateJob", e); + } finally { + daoInfo.getResourceOperation().getTitanGenericDao().commit(); + } + return false; + } + + /** + * @param componentId + * @param nodeTypeEnum + * @return + */ + private boolean updateCache(String componentId, NodeTypeEnum nodeTypeEnum, Long timestamp) { + // get component from cache + Either metaDataRes = getComponentMetaData(componentId, + nodeTypeEnum); + if (metaDataRes.isRight()) { + return false; + } + ComponentMetadataData metaData = metaDataRes.left().value(); + // the job time is older then the one on graph nothing to do there is a + // job that will handle this. + Long graphTimestamp = metaData.getMetadataDataDefinition().getLastUpdateDate(); + if (timestamp < graphTimestamp) { + log.debug( + "the job timestamp:{} is smaller then the graph timestamp:{}. exiting because another job will update the cache.", + timestamp, graphTimestamp); + return false; + } else { + // update cache + // get component from grath + Either componentRes = getOperationByType(nodeTypeEnum) + .getComponent(componentId, true); + if (componentRes.isRight()) { + log.debug("failed to get full component:{} from graph status:{}", componentId, + componentRes.right().value()); + return false; + } + Component component = componentRes.left().value(); + // store in cache + if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) { + log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum); + return false; + } + } + log.debug("cache successfully updated for componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId, + nodeTypeEnum, timestamp); + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java new file mode 100644 index 0000000000..ac1a56f9db --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.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.be.model.cache.jobs; + +import fj.data.Either; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by mlando on 9/20/2016. + */ +public class DeleteJob extends Job { + private static Logger log = LoggerFactory.getLogger(DeleteJob.class.getName()); + + public DeleteJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) { + super(daoInfo, componentId, nodeTypeEnum, timestamp); + + } + + @Override + public Object doWork() { + try { + log.trace("starting work on job."); + log.trace("delete component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, + nodeTypeEnum, timestamp); + ActionStatus status = this.daoInfo.getComponentCache().deleteComponentFromCache(componentId); + if (!ActionStatus.OK.equals(status)) { + log.debug("failed to delete componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum); + return false; + } + log.trace("cache successfully deleted componentId:{} nodeTypeEnum:{} timestamp:{}.", componentId, + nodeTypeEnum, timestamp); + return true; + } catch (Exception e) { + log.debug("an exception was encountered durring deletejob", e); + } + return false; + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java new file mode 100644 index 0000000000..4deda8642f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.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.model.cache.jobs; + +import fj.data.Either; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.openecomp.sdc.be.model.operations.api.IComponentOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class Job { + private static Logger log = LoggerFactory.getLogger(Job.class.getName()); + protected DaoInfo daoInfo; + protected String componentId; + protected long timestamp; + protected NodeTypeEnum nodeTypeEnum; + + protected Job(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) { + this.daoInfo = daoInfo; + this.componentId = componentId; + this.timestamp = timestamp; + this.nodeTypeEnum = nodeTypeEnum; + } + + protected Job(DaoInfo daoInfo, Component component, NodeTypeEnum nodeTypeEnum) { + this.daoInfo = daoInfo; + this.componentId = component.getUniqueId(); + this.timestamp = component.getLastUpdateDate(); + this.nodeTypeEnum = nodeTypeEnum; + } + + public abstract E doWork(); + + protected IComponentOperation getOperationByType(NodeTypeEnum nodeTypeEnum) { + IComponentOperation operation = null; + switch (nodeTypeEnum) { + case Product: + operation = daoInfo.getProductOperation(); + break; + case Service: + operation = daoInfo.getServiceOperation(); + break; + case Resource: + operation = daoInfo.getResourceOperation(); + break; + default: + log.error("unexpected NodeType received no matching operation found."); + } + return operation; + } + + protected Either getComponentMetaData(String componentId, + NodeTypeEnum nodeTypeEnum) { + Either metaDataRes = getOperationByType(nodeTypeEnum) + .getComponentByLabelAndId(componentId, nodeTypeEnum, ComponentMetadataData.class); + if (metaDataRes.isRight()) { + // in case we cant find the component on graph exit + if (StorageOperationStatus.NOT_FOUND.equals(metaDataRes.right().value())) { + log.debug("failed to locate component:{} on graph status:{}", componentId, metaDataRes.right().value()); + } else { + log.debug("failed to get component:{} from graph status:{}", componentId, metaDataRes.right().value()); + } + } + return metaDataRes; + } + + protected NodeTypeEnum getNodeTypeFromComponentType(ComponentTypeEnum type) { + NodeTypeEnum result = null; + switch (type) { + case PRODUCT: + result = NodeTypeEnum.Product; + break; + case RESOURCE: + result = NodeTypeEnum.Resource; + break; + case SERVICE: + result = NodeTypeEnum.Service; + break; + default: + + } + return result; + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java new file mode 100644 index 0000000000..e9da68ea59 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.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.model.cache.jobs; + +import fj.data.Either; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by mlando on 9/20/2016. + */ +public class OverrideJob extends Job { + private static Logger log = LoggerFactory.getLogger(OverrideJob.class.getName()); + + public OverrideJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) { + super(daoInfo, componentId, nodeTypeEnum, timestamp); + + } + + @Override + public Object doWork() { + try { + log.trace("starting work on job."); + log.trace("override component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, + nodeTypeEnum, timestamp); + // get component from grath + Either componentRes = getOperationByType(nodeTypeEnum) + .getComponent(componentId, false); + if (componentRes.isRight()) { + log.debug("failed to get full component:{} from graph status:{}", componentId, + componentRes.right().value()); + return false; + } + Component component = componentRes.left().value(); + // store in cache + if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) { + log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum); + return false; + } + log.debug("cache successfully overrided componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId, + nodeTypeEnum, timestamp); + return true; + } catch (Exception e) { + log.debug("an exception was encountered during OverrideJob", e); + } finally { + this.daoInfo.getResourceOperation().getTitanGenericDao().commit(); + } + return false; + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java new file mode 100644 index 0000000000..410a56a90e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.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.be.model.cache.jobs; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by mlando on 9/11/2016. + */ +public class StoreJob extends Job { + private static Logger log = LoggerFactory.getLogger(StoreJob.class.getName()); + private Component component; + + public StoreJob(DaoInfo daoInfo, Component component, NodeTypeEnum nodeTypeEnum) { + super(daoInfo, component, nodeTypeEnum); + this.component = component; + } + + @Override + public Object doWork() { + try { + log.trace("starting work on job."); + log.trace("store component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, + nodeTypeEnum, timestamp); + if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) { + log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum); + return false; + } + log.debug("cache successfully updated for componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId, + nodeTypeEnum, timestamp); + return true; + + } catch (Exception e) { + log.debug("an exception was encountered during StoreJob", e); + } + return false; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java new file mode 100644 index 0000000000..7d6ff49507 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.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.be.model.cache.workers; + +import org.openecomp.sdc.be.model.cache.jobs.Job; +import org.openecomp.sdc.be.model.cache.workers.IWorker; +import org.openecomp.sdc.be.workers.Worker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * Created by mlando on 9/6/2016. the class represents a worker the pull job + * from a queue and evacuates them. + * + */ +public class CacheWorker implements Runnable, IWorker { + private String workerName; + private static Logger log = LoggerFactory.getLogger(Worker.class.getName()); + private LinkedBlockingQueue jobQueue; + private volatile boolean shutdown = false; + + /** + * constructor + * + * @param workerName + * the name of the given worker + * @param jobQueue + * the queue the worker will block on. + */ + public CacheWorker(String workerName, LinkedBlockingQueue jobQueue) { + this.workerName = workerName; + this.jobQueue = jobQueue; + } + + /** + * the method will try to get a job if one is avilable it will be retrived + * and handled. if no jobs are available the worker will block for 500 + * milliseconds and then it wil check if it needs to shutdown. if not it + * will block again and so on until sutdown or a new job is available + */ + @Override + public void run() { + while (true) { + log.trace("CacheWorker:{} doing work", workerName); + try { + Job job = jobQueue.poll(500, TimeUnit.MILLISECONDS); + if (job != null) { + job.doWork(); + log.trace("worker:{} done with work", workerName); + } + } catch (Throwable e) { + log.debug("worker {} failed during job execution.", workerName); + log.debug("exception", e); + } + if (shutdown) { + log.debug("worker:{} nothing to do stoping", workerName); + break; + } + } + + } + + /** + * the method sets the shutdown flag, when set the worker will stop it's + * execution as soon as possible with out completing its work + */ + @Override + public void shutDown() { + this.shutdown = true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java new file mode 100644 index 0000000000..fcdf9f4148 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.cache.workers; + +/** + * Created by mlando on 9/6/2016. + */ +public interface IWorker { + void shutDown(); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java new file mode 100644 index 0000000000..824dd3496f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java @@ -0,0 +1,266 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.cache.workers; + +import fj.data.Either; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.operations.impl.CacheMangerOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.ComponentCacheData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * the class creates a worker that is used to update cache date, in case of + * failures and inconsistencies + */ +public class SyncWorker implements Runnable, IWorker { + + private static Logger log = LoggerFactory.getLogger(SyncWorker.class.getName()); + private final CacheMangerOperation cacheMangerOperation; + private final String workerName; + private volatile boolean shutdown = false; + private Map cacheIdAndTimeMap; + private long updateDelayInMilliseconds = 60 * 60 * 1000; + + /** + * creates the sync worker + * + * @param workerName + * the name of the worker + * @param cacheMangerOperation + * responsible for all persistence's operations to graph and the + * cache + */ + public SyncWorker(String workerName, CacheMangerOperation cacheMangerOperation) { + this.workerName = workerName; + this.cacheMangerOperation = cacheMangerOperation; + } + + /** + * the method collects all the resources/services/products from graph and + * checks if the component representing them in the cache is valid logic: if + * the record is present in the graph but not in cache -> create a job that + * will update the record oin cache if the timestamp of the record in cache + * is older than the timestamp on the graph -> create a job that will update + * the record oin cache otherwise no update is required + */ + @Override + public void run() { + try { + collectAllCacheRecords(); + syncCacheByComponentType(NodeTypeEnum.Resource); + syncCacheByComponentType(NodeTypeEnum.Service); + syncCacheByComponentType(NodeTypeEnum.Product); + clearCacheRecords(); + + } catch (Exception e) { + log.debug("sync worker:{} encounered an exception", workerName); + log.debug("exception", e); + } finally { + this.cacheMangerOperation.getTitanGenericDao().commit(); + } + } + + /** + * the method checks for each component in the cache except the ones that + * were update during the sync, if they exist on the graph if not a job to + * remove them is created + */ + private void clearCacheRecords() { + cacheIdAndTimeMap.forEach((k, v) -> { + try { + Either componentFromGraphRes = getComponentMetaData(k, + NodeTypeEnum.getByName(v.getType())); + if (componentFromGraphRes.isRight()) { + TitanOperationStatus error = componentFromGraphRes.right().value(); + if (TitanOperationStatus.NOT_FOUND.equals(error)) { + long delay = System.currentTimeMillis() - v.getModificationTime().getTime(); + if (delay > updateDelayInMilliseconds) { + this.cacheMangerOperation.deleteComponentInCache(k, v.getModificationTime().getTime(), + NodeTypeEnum.getByName(v.getType())); + } else { + log.trace( + "no delete done because an hour did not pass since the delete was done timeSinceUpdate {} < updateDelayInMilliseconds {} ", + delay, updateDelayInMilliseconds); + } + } else { + log.debug("failed to get metadata for id:{} from graph error:{}", k, error); + } + } else { + log.trace("id {} is in graph nothing to do"); + } + } catch (Exception e) { + log.debug("during clean cache records an exception was thrown", e); + } + }); + } + + /** + * the method collects all the records from cache except the component + * itself + */ + public void collectAllCacheRecords() { + Either, ActionStatus> getAllRes = this.cacheMangerOperation.getComponentCache() + .getAllComponentIdTimeAndType(); + if (getAllRes.isRight()) { + log.debug("error while trying to get all records from cache error:{}", getAllRes.right().value()); + cacheIdAndTimeMap = new HashMap<>(); + } else { + cacheIdAndTimeMap = getAllRes.left().value().stream().collect(Collectors.toMap(e -> e.getId(), e -> e)); + } + } + + /** + * the method checks that the records ot the given type are sync between the + * cache and the graph + * + * @param nodeTypeEnum + * the type of components we want to sync + */ + private void syncCacheByComponentType(NodeTypeEnum nodeTypeEnum) { + if (!this.shutdown) { + log.trace("syncCache records of type:{} .", nodeTypeEnum); + Either, TitanOperationStatus> getAllResult = getAllComponentsMetaData( + nodeTypeEnum); + List componentList = new ArrayList<>(); + if (getAllResult.isRight() && !TitanOperationStatus.NOT_FOUND.equals(getAllResult.right().value())) { + log.debug("error while trying to get all components of type:{} TitanOperationStatus:{}.", nodeTypeEnum, + getAllResult.right().value()); + return; + } + if (getAllResult.isLeft()) { + componentList = getAllResult.left().value(); + log.trace("get all components of type:{} returned:{} components.", nodeTypeEnum, componentList.size()); + } + componentList.forEach(this::checkAndUpdateCacheComponent); + log.trace("syncCache records of type:{} was successful.", nodeTypeEnum); + } + } + + /** + * the method compares the given component to the record in the cache if the + * record is not in the cache a job to update the cache for this record will + * be created. if the record is present in the graph but not in cache -> + * create a job that will update the record oin cache if the timestamp of + * the record in cache is older than the timestamp on the graph -> create a + * job that will update the record oin cache if the retried component from + * cache fails to be deserialized -> create job to override it otherwise no + * update is required + * + * @param metadataData + * the date of the node we want to compare to the value in the + * cache + */ + private void checkAndUpdateCacheComponent(ComponentMetadataData metadataData) { + long timeSinceUpdate = System.currentTimeMillis() + - metadataData.getMetadataDataDefinition().getLastUpdateDate(); + if (timeSinceUpdate >= updateDelayInMilliseconds) { + String uid = metadataData.getMetadataDataDefinition().getUniqueId(); + log.trace("checking cache if record for uid:{} needs to be updated.", uid); + Either cacheResult = this.cacheMangerOperation.getComponentCache() + .getComponent(uid); + if (cacheResult.isRight()) { + ActionStatus actionStatus = cacheResult.right().value(); + if (ActionStatus.RESOURCE_NOT_FOUND.equals(actionStatus)) { + log.trace("record for uid:{} not found in cache. creating an update job.", uid); + this.cacheMangerOperation.updateComponentInCache(uid, + metadataData.getMetadataDataDefinition().getLastUpdateDate(), + NodeTypeEnum.getByName(metadataData.getLabel())); + } else if (ActionStatus.CONVERT_COMPONENT_ERROR.equals(actionStatus)) { + log.trace("uid:{} found in cache but we failed deserializing it. creating an override job .", uid); + this.cacheMangerOperation.overideComponentInCache(uid, + metadataData.getMetadataDataDefinition().getLastUpdateDate(), + NodeTypeEnum.getByName(metadataData.getLabel())); + } else { + log.debug("during lookup for uid:{} an error accords status:{} .", uid, actionStatus); + } + } else { + log.trace("uid:{} found in cache.", uid); + this.cacheIdAndTimeMap.remove(uid); + Component cacheComponent = cacheResult.left().value(); + Long cacheTimestamp = cacheComponent.getLastUpdateDate(); + Long graphTimestamp = metadataData.getMetadataDataDefinition().getLastUpdateDate(); + if (cacheTimestamp < graphTimestamp) { + log.trace("uid:{} found in cache. cache Timestamp {} < graph timestamp , creating an update job .", + uid, cacheTimestamp, graphTimestamp); + this.cacheMangerOperation.updateComponentInCache(uid, graphTimestamp, + NodeTypeEnum.getByName(metadataData.getLabel())); + } else { + log.trace("uid:{} found in cache. cache Timestamp {} => graph timestamp , no update is needed .", + uid, cacheTimestamp, graphTimestamp); + } + } + } else { + log.trace( + "no update done because an hour did not pass since the update was done timeSinceUpdate {} < updateDelayInMilliseconds {} ", + timeSinceUpdate, updateDelayInMilliseconds); + } + } + + /** + * the method sets the shutdown flag, when set the worker will stop it's + * execution as soon as possible with out completing its work + */ + @Override + public void shutDown() { + log.debug("syncWorker {} shuting down.", workerName); + this.shutdown = true; + } + + /** + * the method retrives all nodes matching the given node type from the graph + * + * @param nodeTypeEnum + * node type we want to lookup on the graph + * @return a list of retrieved nodes matching the given type or not found in + * case no nodes were found or error in case of failure + */ + private Either, TitanOperationStatus> getAllComponentsMetaData( + NodeTypeEnum nodeTypeEnum) { + return this.cacheMangerOperation.getTitanGenericDao().getByCriteria(nodeTypeEnum, null, + ComponentMetadataData.class); + } + + /** + * the method retrieves the metadata from graph for the given id + * + * @param uid + * the unique id of the component we want to retrieve + * @param nodeTypeEnum + * the type of the recored we want to retrieve + * @return the meta dat of the component or the error encountered during the + * get + */ + private Either getComponentMetaData(String uid, + NodeTypeEnum nodeTypeEnum) { + return this.cacheMangerOperation.getTitanGenericDao().getNode(UniqueIdBuilder.getKeyByNodeType(nodeTypeEnum), + uid, ComponentMetadataData.class); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java new file mode 100644 index 0000000000..9286344af6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.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.model.category; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; + +public class CategoryDefinition extends CategoryDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6552733796860992476L; + + List subcategories; + + public CategoryDefinition() { + super(); + } + + public CategoryDefinition(CategoryDataDefinition c) { + super(c); + } + + public List getSubcategories() { + return subcategories; + } + + public void setSubcategories(List subcategories) { + this.subcategories = subcategories; + } + + public void addSubCategory(SubCategoryDefinition subcategory) { + if (subcategories == null) { + subcategories = new ArrayList(); + } + subcategories.add(subcategory); + } + + @Override + public String toString() { + return super.toString() + " CategoryDefinition [subcategories=" + subcategories + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java new file mode 100644 index 0000000000..aeee0a8972 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.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.model.category; + +import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; + +public class GroupingDefinition extends GroupingDataDefinition { + + public GroupingDefinition() { + super(); + } + + public GroupingDefinition(GroupingDataDefinition g) { + super(g); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java new file mode 100644 index 0000000000..14559a1354 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.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.model.category; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; + +public class SubCategoryDefinition extends SubCategoryDataDefinition { + + private List groupings; + + public SubCategoryDefinition() { + super(); + } + + public SubCategoryDefinition(SubCategoryDataDefinition subCategory) { + super(subCategory); + } + + public List getGroupings() { + return groupings; + } + + public void setGroupings(List groupingDefinitions) { + this.groupings = groupingDefinitions; + } + + public void addGrouping(GroupingDefinition groupingDefinition) { + if (groupings == null) { + groupings = new ArrayList(); + } + groupings.add(groupingDefinition); + } + + @Override + public String toString() { + return super.toString() + " SubCategoryDefinition [groupings=" + groupings + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java new file mode 100644 index 0000000000..7de0aa561d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.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.be.model.heat; + +import org.openecomp.sdc.be.model.tosca.converters.DefaultConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatBooleanConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatCommaDelimitedListConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatJsonConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatNumberConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatStringConverter; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.StringConvertor; +import org.openecomp.sdc.be.model.tosca.validators.HeatBooleanValidator; +import org.openecomp.sdc.be.model.tosca.validators.HeatCommaDelimitedListValidator; +import org.openecomp.sdc.be.model.tosca.validators.HeatNumberValidator; +import org.openecomp.sdc.be.model.tosca.validators.HeatStringValidator; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; + +public enum HeatParameterType { + + STRING("string", HeatStringValidator.getInstance(), HeatStringConverter.getInstance()), + + BOOLEAN("boolean", HeatBooleanValidator.getInstance(), HeatBooleanConverter.getInstance()), + + NUMBER("number", HeatNumberValidator.getInstance(), HeatNumberConverter.getInstance()), + + JSON("json", HeatStringValidator.getInstance(), HeatJsonConverter.getInstance()), + + COMMA_DELIMITED_LIST("comma_delimited_list", HeatCommaDelimitedListValidator.getInstance(), HeatCommaDelimitedListConverter.getInstance()); + + private String type; + private PropertyTypeValidator validator; + private PropertyValueConverter converter; + + HeatParameterType(String type, PropertyTypeValidator validator, PropertyValueConverter converter) { + this.type = type; + this.validator = validator; + this.converter = converter; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public PropertyTypeValidator getValidator() { + return validator; + } + + public void setValidator(PropertyTypeValidator validator) { + this.validator = validator; + } + + public PropertyValueConverter getConverter() { + return converter; + } + + public void setConverter(PropertyValueConverter converter) { + this.converter = converter; + } + + public static HeatParameterType isValidType(String typeName) { + if (typeName == null) { + return null; + } + + for (HeatParameterType type : HeatParameterType.values()) { + if (type.getType().equals(typeName)) { + return type; + } + } + return null; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java new file mode 100644 index 0000000000..71167c395f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.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.model.operations.api; + +import java.util.List; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.resources.data.AdditionalInfoParameterData; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IAdditionalInformationOperation { + + public Either addAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String key, String value); + + public Either updateAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String origKey, String key, String value); + + public Either deleteAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String key); + + public Either addAdditionalInformationNode(NodeTypeEnum nodeType, + String resourceUniqueId); + + public Either addAdditionalInformationNode( + NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters); + + public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, + List properties); + + public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, + List properties); + + public Either createAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction); + + public Either updateAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction); + + public Either deleteAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction); + + public Either getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, + String resourceId, boolean inTransaction); + + public Either getNumberOfParameters(NodeTypeEnum nodeType, String resourceId); + + public Either getAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id); + + public Either getAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction); + + public Either getAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification); + + public Either getAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction); + + public Either deleteAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean inTransaction); + + public Either addAdditionalInformationNode(NodeTypeEnum nodeType, + String componentId, TitanVertex matadatVertex); + + public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, + AdditionalInformationDefinition parameters, TitanVertex metadataVertex); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java new file mode 100644 index 0000000000..873d05e1ed --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.api; + +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.resources.data.ArtifactData; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IArtifactOperation { + + public Either addArifactToComponent(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfExist, boolean inTransaction); + + public Either updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction); + + public Either updateArifactDefinition(ArtifactDefinition artifactInfo, boolean inTransaction); + + public Either removeArifactFromResource(String id, String artifactId, NodeTypeEnum resource, boolean deleteMandatoryArtifact, boolean inTransaction); + + public Either, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction); + + public void setTitanGenericDao(TitanGenericDao titanGenericDao); + + public Either getArtifactById(String id, boolean inTransaction); + + public Either, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction, String groupType); + + Either addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifactHeat, String parentId, NodeTypeEnum parentType, boolean inTransaction); + + public void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion); + + public Either getParentsOfArtifact(String artifactId, NodeTypeEnum type); + + public Either getHeatArtifactByHeatEnvId(String heatEnvId, boolean inTransaction); + + public Either updateToscaArtifactNameOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id); + + public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, TitanVertex parentVertex); + + public Either getLatestArtifactDataByArtifactUUID(String artifactUUID, boolean inTransaction); + + StorageOperationStatus addArifactToComponent(TitanVertex artifactInfo, TitanVertex parentVertex, String label); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAttributeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAttributeOperation.java new file mode 100644 index 0000000000..db2b988f5f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAttributeOperation.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.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.AttributeValueData; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IAttributeOperation { + Either deleteAttribute(String attributeId); + + TitanOperationStatus addAttributesToGraph(TitanVertex metadataVertex, Map attributes, String resourceId, Map dataTypes); + + Either, TitanOperationStatus> getAllAttributesOfResourceInstance(ComponentInstance compInstance); + + TitanOperationStatus findAllResourceAttributesRecursively(String resourceId, List attributes); + + Either, StorageOperationStatus> deleteAllAttributeAssociatedToNode(NodeTypeEnum nodeType, String uniqueId); + + TitanOperationStatus findNodeNonInheretedAttribues(String uniqueId, NodeTypeEnum nodeType, List attributes); + + Either addAttribute(AttributeDefinition attributeDefinition, String resourceId); + + Either addAttributeToGraph(AttributeDefinition attribute, String resourceId, Map dataTypes); + + AttributeDefinition convertAttributeDataToAttributeDefinition(AttributeData attributeData, String attributeName, String resourceId); + + Either updateAttribute(String attributeId, AttributeDefinition newAttDef, Map dataTypes); + + /** + * Builds ComponentInstanceAttribute from AttributeValueData + * + * @param attributeValueData + * @param resourceInstanceAttribute + * @return + */ + ComponentInstanceAttribute buildResourceInstanceAttribute(AttributeValueData attributeValueData, ComponentInstanceAttribute resourceInstanceAttribute); + + TitanOperationStatus addAttributeToGraphByVertex(TitanVertex metadataVertex, AttributeDefinition attribute, String resourceId, Map dataTypes); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java new file mode 100644 index 0000000000..52586dad60 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.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.model.operations.api; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.jobs.CheckAndUpdateJob; +import org.openecomp.sdc.be.model.cache.jobs.StoreJob; + +/** + * Created by mlando on 9/5/2016. + */ +public interface ICacheMangerOperation { + + /** + * + * + * @param componentId + * @param timestamp + * @param nodeTypeEnum + */ + void updateComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum); + + void storeComponentInCache(org.openecomp.sdc.be.model.Component component, NodeTypeEnum nodeTypeEnum); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityInstanceOperation.java new file mode 100644 index 0000000000..e50b658121 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityInstanceOperation.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.api; + +import java.util.List; +import java.util.Map; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +/** + * public interface ICapabilityInstanceOperation provides methods for CRUD + * operations for CapabilityInstance on component instance level + * + * @author ns019t + * + */ +public interface ICapabilityInstanceOperation { + /** + * create capability instance of capability with property values for + * resource instance + * + * @param resourceInstanceId + * @param capabilityId + * @param propertyValues + * @param validateCapabilityInstExistance + * @param capabilityName + * @return + */ + public Either>, TitanOperationStatus> createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance( + String resourceInstanceId, String capabilityId, String capabilityName, + List propertyValues, boolean validateCapabilityInstExistance); + + /** + * + * @param resourceInstanceVertex + * @param capabilityId + * @param capabilityName + * @param propertyValues + * @param validateCapabilityInstExistence + * @return + */ + public TitanOperationStatus createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance( + TitanVertex resourceInstanceVertex, String resourceInstanceId, String capabilityId, String capabilityName, + List propertyValues, boolean validateCapabilityInstExistence); + + /** + * validate capability instance uniqueness + * + * @param resourceInstanceId + * @param capabilityId + * @return + */ + public Either validateCapabilityInstExistence(String resourceInstanceId, + String capabilityId); + + /** + * delete capability instance from resource instance + * + * @param resourceInstanceId + * @param capabilityInstanceId + * @return + */ + public Either deleteCapabilityInstanceFromResourceInstance( + String resourceInstanceId, String capabilityInstanceId); + + /** + * get all capability instances for resource instance returns all Capability + * Instances related to Resource Instance as List or + * TitanOperationStatus if error occurs or if Resource Instance have no any + * related Capability Instance + * + * @param resourceInstanceId + * @return Either, TitanOperationStatus> + */ + public Either>, TitanOperationStatus> getAllCapabilityInstancesOfResourceInstance( + String resourceInstanceId); + + /** + * get capability instance of capability for resource instance + * + * @param resourceInstanceId + * @param capabilityId + * @return + */ + public Either getCapabilityInstanceOfCapabilityOfResourceInstance( + String resourceInstanceId, String capabilityId); + + /** + * update capability property values + * + * @param resourceInstanceId + * @param capabilityInstanceId + * @param propertyValues + * @param capabilityId + * @return + */ + public Either, TitanOperationStatus> updateCapabilityPropertyValues( + String resourceInstanceId, String capabilityId, List propertyValues); + + /** + * clone and associate capability instance with property values + * + * @param createdComponentInstance + * @param capability + * @param capabilityInstPair + * @return + */ + public Either>, TitanOperationStatus> cloneAssociateCapabilityInstanceWithPropertyValues( + ComponentInstanceData createdComponentInstance, CapabilityDefinition capability, + ImmutablePair capabilityInstPair); + + Either validateCapabilityInstExistence(TitanVertex instanceVertex, + String resourceInstanceId, String capabilityId); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java new file mode 100644 index 0000000000..3b692b9607 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.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.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.PropertyData; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface ICapabilityOperation { + + public Either addCapability(String resourceId, String capabilityName, + CapabilityDefinition capabilityDefinition); + + public Either addCapability(String resourceId, String capabilityName, + CapabilityDefinition capabilityDefinition, boolean inTransaction); + + /** + * @param uniqueId + * @return + */ + public Either getCapability(String uniqueId); + + public Either getCapability(String uniqueId, boolean inTransaction); + + public Either getCapability(String capabilityName, String resourceId); + + public Either getCapability(String capabilityName, String resourceId, + boolean inTransaction); + + public Either>, TitanOperationStatus> getAllCapabilitiesPairs( + String resourceId); + + public Either, StorageOperationStatus> deleteAllCapabilities(String resourceId, + boolean inTransaction); + + public Either getCapabilityByCapabilityData( + CapabilityData capabilityData); + + public TitanOperationStatus getCapabilitySourcesList(String resourceId, List derivedFromList); + + public Either, StorageOperationStatus> updatePropertiesOfCapability(String uniqueId, + String capabilityType, List newProperties); + + public Either, StorageOperationStatus> updatePropertiesOfCapability(String uniqueId, + String capabilityType, List newProperties, boolean inTransaction); + + StorageOperationStatus addCapability(TitanVertex metadataVertex, String resourceId, String capabilityName, + CapabilityDefinition capabilityDefinition, boolean inTransaction); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java new file mode 100644 index 0000000000..6f0b5b8d13 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.api; + +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; + +import fj.data.Either; + +public interface ICapabilityTypeOperation { + + /** + * @param capabilityTypeDefinition + * @return + */ + public Either addCapabilityType( + CapabilityTypeDefinition capabilityTypeDefinition); + + public Either addCapabilityType( + CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction); + + /** + * @param uniqueId + * @return + */ + public Either getCapabilityType(String uniqueId); + + public Either getCapabilityType(String uniqueId, + boolean inTransaction); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java new file mode 100644 index 0000000000..e51e077906 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java @@ -0,0 +1,246 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +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.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.resources.data.AttributeValueData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; + +import fj.data.Either; + +public interface IComponentInstanceOperation { + + /** + * add resource instance to service + * + * @param containerComponentId + * - component id + * @param instanceNumber + * - instance number of the component instance + * @param componentInstance + * @param inTransaction + * @return + */ + public Either createComponentInstance(String containerComponentId, + NodeTypeEnum containerNodeType, String instanceNumber, ComponentInstance componentInstance, + NodeTypeEnum instNodeType, boolean inTransaction); + + /** + * add resource instance to service with internal transaction + * + * @param containerComponentId + * @param instanceNumber + * @param componentInstance + * @return + */ + public Either createComponentInstance(String containerComponentId, + NodeTypeEnum containerNodeType, String instanceNumber, ComponentInstance componentInstance, + NodeTypeEnum instNodeType); + + /** + * delete resource instance from component + * + * @param containerComponentId + * - containerComponent id + * @param resourceInstUid + * - resource instance uid + * @param inTransaction + * @return + */ + public Either deleteComponentInstance(NodeTypeEnum containerNodeType, + String containerComponentId, String resourceInstUid, boolean inTransaction); + + public Either deleteComponentInstance(NodeTypeEnum containerNodeType, + String containerComponentId, String resourceInstUid); + + /** + * associate 2 resource instances for a given requirement + * + * @param serviceId + * @param fromResInstanceUid + * @param toResInstanceUid + * @param requirement + * @param relationship + * @param inTransaction + * @return + */ + // public Either + // associateResourceInstances( + // String serviceId, NodeTypeEnum nodeType, String fromResInstanceUid, + // String toResInstanceUid, String requirement, String relationship, + // boolean inTransaction); + + // public Either + // associateResourceInstances( + // String serviceId, NodeTypeEnum nodeType, String fromResInstanceUid, + // String toResInstanceUid, String requirement, String relationship); + + public Either associateResourceInstances(String serviceId, + NodeTypeEnum nodeType, RequirementCapabilityRelDef relation, boolean inTransaction); + + public Either associateResourceInstances(String serviceId, + NodeTypeEnum nodeType, RequirementCapabilityRelDef relation); + + /** + * + * dissociate the relation between 2 resource instances for a given + * requirement + * + * @param serviceId + * @param fromResInstanceUid + * @param toResInstanceUid + * @param requirement + * @param inTransaction + * @return + */ + public Either dissociateResourceInstances(String serviceId, + NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef, boolean inTransaction); + + public Either dissociateResourceInstances(String serviceId, + NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef); + + /** + * update the properties of a given resource instance + * + * @param serviceId + * @param resourceInstanceName + * @param resourceInstance + * @param inTransaction + * @return + */ + public Either updateResourceInstance(String serviceId, + NodeTypeEnum nodeType, String resourceInstanceName, ComponentInstance resourceInstance, + boolean inTransaction); + + public Either updateResourceInstance(String serviceId, + NodeTypeEnum nodeType, String resourceInstanceName, ComponentInstance resourceInstance); + + /** + * get all resource instances of a given service and the relations between + * the resource instances + * + * @param serviceId + * @param inTransaction + * @return + */ + public Either, List>, StorageOperationStatus> getAllComponentInstances( + String componentId, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, boolean inTransaction); + + public Either, StorageOperationStatus> getAllComponentInstancesNames(String componentId, + NodeTypeEnum nodeType, boolean inTransaction); + + public Either, StorageOperationStatus> getAllComponentInstancesNames(String componentId, + NodeTypeEnum nodeType); + + /** + * get resource instance from id + * + * @param resourceId + * @return resource instance of given id + */ + public Either getResourceInstanceById(String resourceId); + + public Either, StorageOperationStatus> deleteAllComponentInstances(String serviceId, + NodeTypeEnum nodeType, boolean inTransaction); + + public Either, StorageOperationStatus> deleteAllComponentInstances(String serviceId, + NodeTypeEnum nodeType); + + public Either increaseAndGetResourceInstanceSpecificCounter( + String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction); + + public String createComponentInstLogicalName(String instanceNumber, String componentInstanceName); + + public Either isComponentInstanceNameExist(String parentComponentId, + NodeTypeEnum parentNodeType, String compInstId, String componentInstName); + + public Either validateParent(String parentId, String uniqId, + boolean inTransaction); + + public Either getFullComponentInstance( + ComponentInstance componentInstance, NodeTypeEnum compInstNodeType); + + public Either isAvailableRequirement(ComponentInstance fromResInstance, + RequirementAndRelationshipPair relationPair); + + public Either isAvailableCapabilty(ComponentInstance toResInstance, + RequirementAndRelationshipPair relationPair); + + public Either addPropertyValueToResourceInstance( + ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, + boolean inTransaction); + + public Either addPropertyValueToResourceInstance( + ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean isvalidate, + Integer index, boolean inTransaction); + + /** + * Adds Attribute to resource instance + * + * @param resourceInstanceAttribute + * * @param resourceInstanceId * @param index * @param + * inTransaction + * @return + **/ + public Either addAttributeValueToResourceInstance( + ComponentInstanceAttribute resourceInstanceAttribute, String resourceInstanceId, Integer index, + boolean inTransaction); + + public Either updatePropertyValueInResourceInstance( + ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction); + + /** + * Updates Attribute on resource instance + * + * @param attribute + * @param resourceInstanceId + * @param inTransaction + * @return + */ + public Either updateAttributeValueInResourceInstance( + ComponentInstanceAttribute attribute, String resourceInstanceId, boolean inTransaction); + + public Either createOrUpdateAttributeOfResourceInstance( + ComponentInstanceAttribute attributeInstanceProperty, String resourceInstanceId); + + public Either addInputValueToResourceInstance( + ComponentInstanceInput input, String resourceInstanceId, Integer innerElement, boolean b); + + public Either updateInputValueInResourceInstance( + ComponentInstanceInput input, String resourceInstanceId, boolean b); + + public Either, StorageOperationStatus> fetchCIEnvArtifacts( + String componentInstanceId); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentOperation.java new file mode 100644 index 0000000000..e7eff13a9d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentOperation.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.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; + +import fj.data.Either; + +public interface IComponentOperation { + public Either getComponent(String id, Class clazz); + + public Either, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, + NodeTypeEnum parentType, boolean inTransacton); + + public Either getLightComponent(String id, boolean inTransaction); + + public Either getComponent(String id, boolean inTransaction); + + public Either, StorageOperationStatus> getFilteredComponents(Map filters, + boolean inTranscation); + + public Either getComponentByLabelAndId(String uniqueId, + NodeTypeEnum nodeType, Class clazz); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java new file mode 100644 index 0000000000..290552b382 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.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.be.model.operations.api; + +import org.openecomp.sdc.be.resources.data.ConsumerData; + +import fj.data.Either; + +public interface IConsumerOperation { + + /** + * the method updates the node in the graph with the given ConsumerData + * + * @param consumerData + * the object we want to store + * @param inTransaction + * inTransaction is the operation part of a transaction, in case + * the value is false the action will be committed in the end of + * the method + * @return the updated object returned from the graph + */ + Either updateCredentials(ConsumerData consumerData, boolean inTransaction); + + /** + * the method updates the node in the graph with the given ConsumerData + * + * @param consumerData + * the object we want to store + * @return the updated object returned from the graph + */ + Either updateCredentials(ConsumerData consumerData); + + /** + * the method deletes the node with the given unique id + * + * @param consumerName + * the unique id by witch we will look up the credential we want + * to delete + * @param inTransaction + * inTransaction is the operation part of a transaction, in case + * the value is false the action will be committed in the end of + * the method + * @return the deleted object returned from the graph + */ + Either deleteCredentials(String consumerName, boolean inTransaction); + + /** + * the method deletes the node with the given unique id + * + * @param consumerName + * the unique id by witch we will look up the credential we want + * to delete + * @return the deleted object returned from the graph + */ + Either deleteCredentials(String consumerName); + + /** + * the method creates a new nod in the grape representing the supplied + * credential object + * + * @param consumerData + * the object we want to store + * @param inTransaction + * is the operation part of a transaction, in case the value is + * false the action will be committed in the end of the method + * @return the newly stored object returned from the graph + */ + Either createCredentials(ConsumerData consumerData, boolean inTransaction); + + /** + * the method creates a new nod in the grape representing the supplied + * credential object + * + * @param consumerData + * the object we want to store + * @return the newly stored object returned from the graph + */ + Either createCredentials(ConsumerData consumerData); + + /** + * the method retrieves the credential for the given consumer name + * + * @param consumerName + * the unique id by witch we will look up the credential + * @return ConsumerData or the error received during the operation + */ + Either getCredentials(String consumerName); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java new file mode 100644 index 0000000000..b7f1882b45 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.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.model.operations.api; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +import fj.data.Either; + +public interface IDataTypeOperation { + + /** + * @param dataTypeDefinition + * @return + */ + public Either addDataType(DataTypeDefinition dataTypeDefinition); + + public Either addDataType(DataTypeDefinition dataTypeDefinition, + boolean inTransaction); + + /** + * @param name + * @return + */ + public Either getDataTypeByName(String name); + + public Either getDataTypeByName(String name, boolean inTransaction); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java new file mode 100644 index 0000000000..a21c194060 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.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.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.PropertyScope; +import org.openecomp.sdc.be.model.Tag; +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.CategoryData; + +import fj.data.Either; + +public interface IElementOperation { + + Either, ActionStatus> getAllResourceCategories(); + + Either, ActionStatus> getAllServiceCategories(); + + Either, ActionStatus> getAllProductCategories(); + + public Either, ActionStatus> getAllTags(); + + public Either, ActionStatus> getAllPropertyScopes(); + + public Either, ActionStatus> getAllArtifactTypes(); + + public Either, ActionStatus> getAllDeploymentArtifactTypes(); + + public Either getDefaultHeatTimeout(); + + public Either getCategoryData(String name, + NodeTypeEnum type, Class clazz); + + public Either getNewCategoryData( + String name, NodeTypeEnum type, Class clazz); + + public Either, ActionStatus> getResourceTypesMap(); + + Either createCategory(CategoryDefinition category, NodeTypeEnum nodeType); + + Either createCategory(CategoryDefinition category, NodeTypeEnum nodeType, + boolean inTransaction); + + Either deleteCategory(NodeTypeEnum nodeType, String categoryId); + + Either deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId); + + Either isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName); + + Either createSubCategory(String categoryId, SubCategoryDefinition subCategory, + NodeTypeEnum nodeType); + + Either createSubCategory(String categoryId, SubCategoryDefinition subCategory, + NodeTypeEnum nodeType, boolean inTransaction); + + Either, ActionStatus> getAllCategories(NodeTypeEnum nodeType, boolean inTransaction); + + Either getCategory(NodeTypeEnum nodeType, String categoryId); + + Either getSubCategoryUniqueForType(NodeTypeEnum nodeType, + String normalizedName); + + Either isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, String subCategoryNormName, + String parentCategoryId); + + Either createGrouping(String subCategoryId, GroupingDefinition grouping, + NodeTypeEnum nodeType); + + Either deleteGrouping(NodeTypeEnum nodeType, String groupingId); + + Either getSubCategory(NodeTypeEnum nodeType, String subCategoryId); + + Either isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, + String parentSubCategoryId); + + Either getGroupingUniqueForType(NodeTypeEnum nodeType, + String groupingNormalizedName); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java new file mode 100644 index 0000000000..d065ce0b09 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.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.model.operations.api; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; + +public interface IGraphLockOperation { + + public abstract StorageOperationStatus lockComponent(String componentId, NodeTypeEnum nodeType); + + public abstract StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType); + + public abstract StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType); + + public abstract StorageOperationStatus unlockComponentByName(String name, String componentId, + NodeTypeEnum nodeType); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java new file mode 100644 index 0000000000..4252ec0622 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.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.be.model.operations.api; + +import java.util.List; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.GroupData; + +import fj.data.Either; + +public interface IGroupOperation { + + // add full group to component + public Either addGroupToGraph(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition); + + public Either addGroup(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition); + + public Either addGroup(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition, boolean inTransaction); + + public Either, StorageOperationStatus> addGroups(NodeTypeEnum nodeTypeEnum, + String componentId, List groups, boolean inTransaction); + + // get group + public Either getGroupFromGraph(String uniqueId); + + public Either getGroup(String uniqueId); + + public Either getGroup(String uniqueId, boolean inTransaction); + + // get all groups under component + public Either, TitanOperationStatus> getAllGroupsFromGraph(String componentId, + NodeTypeEnum componentTypeEnum); + + public Either, StorageOperationStatus> getAllGroups(String componentId, + NodeTypeEnum compTypeEnum, boolean inTransaction); + + public Either, StorageOperationStatus> getAllGroups(String componentId, + NodeTypeEnum compTypeEnum); + + // delete all groups under component + public Either, TitanOperationStatus> deleteAllGroupsFromGraph(String componentId, + NodeTypeEnum compTypeEnum); + + public Either, StorageOperationStatus> deleteAllGroups(String componentId, + NodeTypeEnum compTypeEnum, boolean inTransaction); + + public Either, StorageOperationStatus> deleteAllGroups(String componentId, + NodeTypeEnum compTypeEnum); + + // Association + public Either, StorageOperationStatus> getAssociatedGroupsToComponentInstance( + String componentInstanceId, boolean inTransaction); + + public Either, StorageOperationStatus> getAssociatedGroupsToComponentInstance( + String componentInstanceId); + + public Either, TitanOperationStatus> getAssociatedGroupsToComponentInstanceFromGraph( + String componentInstanceId); + + public StorageOperationStatus associateGroupsToComponentInstance(List groups, String componentInstanceId, + String compInstName, boolean inTransaction); + + public StorageOperationStatus associateGroupsToComponentInstance(List groups, String componentInstanceId, + String compInstName); + + public Either, TitanOperationStatus> associateGroupsToComponentInstanceOnGraph( + List groups, String componentInstanceId, String compInstName); + + public Either, TitanOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, + NodeTypeEnum componentTypeEnum, String artifactId); + + public StorageOperationStatus dissociateAllGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId, boolean inTransaction); + + public StorageOperationStatus dissociateAllGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId); + + public TitanOperationStatus dissociateAndAssociateGroupsFromArtifactOnGraph(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact); + + public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction); + + public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact); + + public boolean isGroupExist(String groupName, boolean inTransaction); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java new file mode 100644 index 0000000000..2b612579b6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.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.be.model.operations.api; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.resources.data.GroupTypeData; + +import fj.data.Either; + +public interface IGroupTypeOperation { + + /** + * @param groupTypeDefinition + * @return + */ + public Either addGroupType(GroupTypeDefinition groupTypeDefinition); + + public Either addGroupType(GroupTypeDefinition groupTypeDefinition, + boolean inTransaction); + + /** + * @param uniqueId + * @return + */ + public Either getGroupType(String uniqueId); + + public Either getGroupType(String uniqueId, boolean inTransaction); + + public Either getLatestGroupTypeByType(String name); + + public Either getLatestGroupTypeByType(String name, + boolean inTransaction); + + public Either getGroupTypeByTypeAndVersion(String name, + String version); + + public Either getGroupTypeByTypeAndVersion(String name, String version, + boolean inTransaction); + + public Either getLatestGroupTypeByNameFromGraph(String name); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java new file mode 100644 index 0000000000..f903b4fc41 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.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.model.operations.api; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.resources.data.HeatParameterValueData; + +import fj.data.Either; + +public interface IHeatParametersOperation { + + public StorageOperationStatus addPropertiesToGraph(List properties, String resourceId, NodeTypeEnum nodeType); + + public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List properties); + + public Either, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId); + + public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId); + + public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition heatParam); + + public Either updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel); + + public StorageOperationStatus updateHeatParameters(List properties); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java new file mode 100644 index 0000000000..2f1f2a70cf --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.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.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.InputsData; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IInputsOperation { + + Either deleteInput(String inputId); + + Either, TitanOperationStatus> addInputsToGraph(String componentId, NodeTypeEnum nodeType, + Map inputs, Map dataTypes); + + Either, StorageOperationStatus> addInputsToComponent(String resourceId, NodeTypeEnum nodeType, + ComponentInstInputsMap componentInsInputs, Map dataTypes); + + TitanOperationStatus findNodeNonInheretedInputs(String uniqueId, List inputs); + + Either, StorageOperationStatus> getInputsOfComponent(String compId, String fromName, + int amount); + + Either, TitanOperationStatus> getAllInputsOfResourceInstance( + ComponentInstance compInstance); + + Either, StorageOperationStatus> deleteAllInputsAssociatedToNode(NodeTypeEnum nodeType, + String uniqueId); + + // TitanOperationStatus findNodeNonInheretedAttribues(String uniqueId, + // NodeTypeEnum nodeType, List attributes); + + Either addInput(String inputName, InputDefinition inputDefinition, + String componentId, NodeTypeEnum nodeType); + + Either addInputToGraph(String propertyName, InputDefinition inputDefinition, + String componentId, NodeTypeEnum nodeType); + + Either updateInput(String inputId, InputDefinition newInDef, + Map dataTypes); + + TitanOperationStatus findAllResourceInputs(String uniqueId, List inputs); + + Either getInputById(String uniqueId, boolean skipProperties, + boolean skipinputsValue); + + TitanOperationStatus addInputsToGraph(TitanVertex metadata, String componentId, Map inputs, + Map dataTypes); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java new file mode 100644 index 0000000000..bbcb61fea8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.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.model.operations.api; + +import java.util.Map; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Operation; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IInterfaceLifecycleOperation { + + public Either createInterfaceOnResource(InterfaceDefinition interf, + String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction); + + public StorageOperationStatus createInterfaceOnResource(InterfaceDefinition interf, String resourceId, + String interfaceName, boolean failIfExist, boolean inTransaction, TitanVertex metadataVertex); + + public Either addInterfaceToResource(InterfaceDefinition interf, + String resourceId, String interfaceName); + + public Either addInterfaceToResource(InterfaceDefinition interf, + String resourceId, String interfaceName, boolean inTransaction); + + // public Either + // getInterface(String interfaceId); + // + // public Either + // getInterface(String interfaceId, boolean inTransaction); + + public Either updateInterfaceOperation(String resourceId, String interfaceName, + String operationName, Operation interf); + + public Either updateInterfaceOperation(String resourceId, String interfaceName, + String operationName, Operation interf, boolean inTransaction); + + public Either deleteInterfaceOperation(String resourceId, String interfaceName, + String operationName); + + public Either deleteInterfaceOperation(String resourceId, String interfaceName, + String operationName, boolean inTransaction); + + public Either, StorageOperationStatus> getAllInterfacesOfResource( + String resourceId, boolean recursively, boolean inTransaction); + + public Either, StorageOperationStatus> getAllInterfacesOfResource( + String resourceId, boolean recursively); + + public Either deleteInterfaceOfResourceOnGraph(String resourceId, + InterfaceDefinition interfaceDef, boolean inTransaction); + + public Either createInterfaceType(InterfaceDefinition interf); + + public Either createInterfaceType(InterfaceDefinition interf, + boolean inTransaction); + + public Either getInterface(String interfaceId); + + public StorageOperationStatus associateInterfaceToNode(GraphNode node, InterfaceDefinition interfaceDefinition, + TitanVertex metadataVertex); + + public Either getSpecificOperation(String resourceId, String interfaceType, + String operationName); + + public Either dissociateInterfaceFromNode(GraphNode node, + InterfaceDefinition interfaceDefinition); + + public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ILifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ILifecycleOperation.java new file mode 100644 index 0000000000..3b82eb692c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ILifecycleOperation.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.model.operations.api; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; + +import fj.data.Either; + +public interface ILifecycleOperation { + + public ResourceOperation getResourceOperation(); + + public Either getComponentOwner(String resourceId, NodeTypeEnum nodeType, + boolean inTransaction); + + public Either checkinComponent(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction); + + public Either requestCertificationComponent(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction); + + public Either startComponentCertification(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction); + + public Either checkoutComponent(NodeTypeEnum nodeType, + Component component, User modifier, User currentOwner, boolean inTransaction); + + public Either certifyComponent(NodeTypeEnum nodeType, + Component component, User modifier, User currentOwner, boolean inTransaction); + + public Either cancelOrFailCertification(NodeTypeEnum nodeType, + Component component, User modifier, User owner, LifecycleStateEnum nextState, boolean b); + + public Either deleteOldComponentVersions(NodeTypeEnum nodeType, + String componentName, String uuid, boolean inTransaction); + + public Either undoCheckout(NodeTypeEnum nodeType, Component resource, + User modifier, User currentOwner, boolean inTransaction); + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java new file mode 100644 index 0000000000..fc689c81e2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.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.be.model.operations.api; + +import org.openecomp.sdc.be.model.PolicyTypeDefinition; + +import fj.data.Either; + +public interface IPolicyTypeOperation { + + Either getLatestPolicyTypeByType(String policyTypeName); + + Either addPolicyType(PolicyTypeDefinition policyType); + + Either getPolicyType(String uniqueId, boolean inTransaction); + + Either addPolicyType(PolicyTypeDefinition policyType, + boolean inTransaction); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IProductOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IProductOperation.java new file mode 100644 index 0000000000..bbfea262a7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IProductOperation.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.api; + +import java.util.List; +import java.util.Set; + +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; + +import fj.data.Either; + +public interface IProductOperation extends IComponentOperation { + public Either, StorageOperationStatus> getProductCatalogData(boolean inTransaction); + + public Either createProduct(Product product); + + public Either createProduct(Product product, boolean inTransaction); + + public Either deleteProduct(String productId, boolean inTransaction); + + public Either, StorageOperationStatus> getFollowed(String userId, + Set lifecycleStates, Set lastStateStates, boolean inTransaction); + + public void rollback(); + + public void commit(); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java new file mode 100644 index 0000000000..6309510f6d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.api; + +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.IComplexDefaultValue; +import org.openecomp.sdc.be.model.PropertyDefinition; + +import fj.data.Either; + +public interface IPropertyOperation { + + /** + * add property to resource + * + * @param propertyName + * @param propertyDefinition + * @param nodeType + * @param id + * @return + * + * public Either + * addPropertyToResource( String propertyName, PropertyDefinition + * propertyDefinition, NodeTypeEnum nodeType, String id); + */ + + /** + * get property belongs to resource + * + * @param propertyName + * - property name + * @param resourceId + * - resource unique id + * @return + */ + public Either getPropertyOfResource(String propertyName, + String resourceId); + + /** + * Delete all properties of resource + * + * @param nodeType + * @param uniqueId + * @return + */ + public Either, StorageOperationStatus> deleteAllPropertiesAssociatedToNode( + NodeTypeEnum nodeType, String uniqueId); + + public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, + Map dataTypes); + + public boolean isPropertyTypeValid(IComplexDefaultValue propertyDefinition); + + public ImmutablePair isPropertyInnerTypeValid(IComplexDefaultValue propertyDefinition, + Map dataTypes); + + /** + * @param dataTypeDefinition + * @return + */ + public Either addDataType(DataTypeDefinition dataTypeDefinition); + + public Either addDataType(DataTypeDefinition dataTypeDefinition, + boolean inTransaction); + + /** + * @param name + * @return + */ + public Either getDataTypeByName(String name); + + public Either getDataTypeByName(String name, boolean inTransaction); + + public Either getDataTypeByNameWithoutDerived(String name, + boolean inTransaction); + + public Either getDataTypeByNameWithoutDerived(String name); + + public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, + Map dataTypes); + + public Either updateDataType(DataTypeDefinition newDataTypeDefinition, + DataTypeDefinition oldDataTypeDefinition, boolean inTransaction); + + public Either updateDataType(DataTypeDefinition newDataTypeDefinition, + DataTypeDefinition oldDataTypeDefinition); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IRequirementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IRequirementOperation.java new file mode 100644 index 0000000000..a7a9bf6013 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IRequirementOperation.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.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.RequirementImplDef; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IRequirementOperation { + + /** + * add a requirement to resource + * + * @param reqName + * @param reqDefinition + * @param nodeType + * @param uniqueId + * @return + */ + public Either addRequirementToResource(String reqName, + RequirementDefinition reqDefinition, String resourceId); + + public Either addRequirementToResource(String reqName, + RequirementDefinition reqDefinition, String resourceId, boolean inTransaction); + + public Either addRequirementImplToResource(String reqName, + RequirementImplDef reqDefinition, String resourceId, String parentReqUniqueId); + + public Either addRequirementImplToResource(String reqName, + RequirementImplDef reqDefinition, String resourceId, String parentReqUniqueId, boolean inTransaction); + + /** + * get requirement of resource + * + * @param reqName + * @param resourceId + * @return + */ + public Either getRequirementOfResource(String reqName, + String resourceId); + + public Either getRequirementOfResource(String reqName, + String resourceId, boolean inTransaction); + + public Either, StorageOperationStatus> getAllResourceRequirements( + String resourceId, boolean inTransaction); + + Either>, StorageOperationStatus> getAllRequirementsOfResourceOnly( + String resourceId, boolean inTransaction); + + public Either, TitanOperationStatus> getResourceRequirements(String resourceId); + + public Either, StorageOperationStatus> deleteAllRequirements(String resourceId, + boolean inTransaction); + + public Either getRequirement(String uniqueId); + + StorageOperationStatus addRequirementToResource(TitanVertex metadataVertex, String reqName, + RequirementDefinition reqDefinition, String resourceId, boolean inTransaction); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IResourceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IResourceOperation.java new file mode 100644 index 0000000000..759380c236 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IResourceOperation.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.api; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; + +import fj.data.Either; + +public interface IResourceOperation extends IComponentOperation { + + public TitanGenericDao getTitanGenericDao(); + + // public StorageOperationStatus lockResource(Resource resource); + // + // public StorageOperationStatus unlockResource(Resource resource); + + public Either createResource(Resource resource); + + public Either createResource(Resource resource, boolean inTransaction); + + public Either getResource(String resourceId); + + // public Either getResource_tx(String + // resourceId,boolean inTransaction); + + public Either getResource(String resourceId, boolean inTransaction); + + /** + * the method retrieves all the certified resources, the returned values are + * only abstract or only none abstract according to the supplied parameters. + * + * @param getAbstract + * the value defines which resources to return only abstract or + * only none abstract + * @return + */ + public Either, StorageOperationStatus> getAllCertifiedResources(boolean getAbstract); + + public Either, StorageOperationStatus> getAllCertifiedResources(boolean getAbstract, + Boolean isHighest); + + public Either validateResourceNameExists(String resourceName, + ResourceTypeEnum resourceType); + + public Either deleteResource(String resourceId); + + public Either deleteResource(String resourceId, boolean inTransaction); + + public Either updateResource(Resource resource); + + public Either updateResource(Resource resource, boolean inTransaction); + + public Either getNumberOfResourcesByName(String resourceName); + + // public Either, StorageOperationStatus> + // getResourceArtifactsForDelete(Resource resource); + + public Either, StorageOperationStatus> getFollowed(String userId, + Set lifecycleStates, Set lastStateStates, boolean inTransaction); + + public Either, StorageOperationStatus> getCatalogData(Map propertiesToMatch, + boolean inTransaction); + + public Either getLatestByName(String resourceName, boolean inTransaction); + + public Either overrideResource(Resource resource, Resource resourceSaved, + boolean inTransaction); + + public Either, StorageOperationStatus> getTesterFollowed(String userId, + Set lifecycleStates, boolean inTransaction); + + public Either, StorageOperationStatus> getResourceListByUuid(String uuid, boolean inTransaction); + + public Either, StorageOperationStatus> getLatestResourceByUuid(String uuid, boolean inTransaction); + + public Either, StorageOperationStatus> getResourceListBySystemName(String systemName, + boolean inTransaction); + + public Either, StorageOperationStatus> getResourceCatalogData(boolean inTransaction); + + public Either, StorageOperationStatus> getResourceCatalogDataVFLatestCertifiedAndNonCertified( + boolean inTransaction); + + public Either, StorageOperationStatus> getResourceByNameAndVersion(String name, String version, + boolean inTransaction); + + public Either, StorageOperationStatus> getResourceByNameAndVersion(String name, String version); + + public Either getResourceBySystemNameAndVersion(String name, String version, + Map additionalParams, boolean inTransaction); + + // public Either, StorageOperationStatus> + // getAllNotCheckoutResources(boolean getAbstract); + + // public Either, StorageOperationStatus> + // getAllNotCheckoutResources(boolean getAbstract, Boolean isHighest); + + public Either, StorageOperationStatus> getAllResourcesMarkedForDeletion(); + + public Either isResourceInUse(String resourceToDelete); + + public Either getLatestByToscaResourceName(String toscaResourceName, + boolean inTransaction); + + public Either validateToscaResourceNameExists(String templateName); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IServiceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IServiceOperation.java new file mode 100644 index 0000000000..05eb7c66f6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IServiceOperation.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.be.model.operations.api; + +import java.util.List; +import java.util.Map; +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 fj.data.Either; + +public interface IServiceOperation extends IComponentOperation { + + public Either createService(Service service); + + public Either createService(Service service, boolean inTransaction); + + public Either getService(String uniqueId); + + public Either getService(String uniqueId, boolean inTransaction); + // public Either getService_tx(String + // uniqueId, boolean inTransaction); + + public Either deleteService(String uniqueId); + + public Either deleteService(String uniqueId, boolean inTransaction); + + public Either validateServiceNameExists(String serviceName); + + public Either, StorageOperationStatus> getFollowed(String userId, + Set lifecycleStates, Set lastStateStates, boolean inTransaction); + + public Either updateService(Service service, boolean inTransaction); + + public Either, StorageOperationStatus> getCatalogData(Map propertiesToMatch, + boolean inTransaction); + + public Either, StorageOperationStatus> getTesterFollowed(String userId, + Set lifecycleStates, boolean inTransaction); + + public Either, StorageOperationStatus> getCertifiedServicesWithDistStatus( + Map propertiesToMatch, Set distStatus, boolean inTransaction); + + public Either updateDestributionStatus(Service service, User user, + DistributionStatusEnum distributionStatus); + + public Either, StorageOperationStatus> getServiceCatalogData(boolean inTransaction); + + public Either, StorageOperationStatus> getServiceCatalogDataLatestCertifiedAndNotCertified( + boolean inTransaction); + + public Either getServiceByNameAndVersion(String name, String version, + Map additionalParams, boolean inTransaction); + + public Either getServiceByNameAndVersion(String name, String version); + + public Either getServiceBySystemNameAndVersion(String name, String version, + boolean inTransaction); + + public Either, StorageOperationStatus> getServiceListByUuid(String uuid, boolean inTransaction); + + public Either, StorageOperationStatus> getLatestServiceByUuid(String uuid, boolean inTransaction); + + public Either, StorageOperationStatus> getServiceListBySystemName(String systemName, + boolean inTransaction); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java new file mode 100644 index 0000000000..dd9766fc83 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.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.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.FunctionalMenuInfo; +import org.openecomp.sdc.be.model.User; + +import fj.data.Either; + +public interface IUserAdminOperation { + + public Either getUserData(String id, boolean inTransaction); + + public Either getInactiveUserData(String id); + + public Either saveUserData(User user); + + public Either updateUserData(User user); + + public Either deActivateUser(User user); + + public Either deleteUserData(String id); + + public Either, ActionStatus> getAllUsersWithRole(String role, String status); + + public Either, StorageOperationStatus> getUserPandingTasksList(User user, + Map properties); + + public Either, ActionStatus> getUserDataWithFunctionalMenu(String userId); + + public Either createOrUpdateFunctionalMenu(String userId, + String newFunctionalMenu); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java new file mode 100644 index 0000000000..c2346a316a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.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.model.operations.api; + +public enum StorageOperationStatus { + + OK, CONNECTION_FAILURE, BAD_REQUEST, ENTITY_ALREADY_EXISTS, GRAPH_IS_LOCK, GENERAL_ERROR, USER_NOT_FOUND, PERMISSION_ERROR, HTTP_PROTOCOL_ERROR, STORAGE_NOT_AVAILABLE, READ_ONLY_STORAGE, STORAGE_LEGACY_INDEX_ERROR, SCHEMA_ERROR, TRANSACTION_ERROR, EXEUCTION_FAILED, NOT_FOUND, OPERATION_NOT_SUPPORTED, CATEGORY_NOT_FOUND, PARENT_RESOURCE_NOT_FOUND, MULTIPLE_PARENT_RESOURCE_FOUND, INCONSISTENCY, GRAPH_IS_NOT_AVAILABLE, SCHEMA_VIOLATION, FAILED_TO_LOCK_ELEMENT, INVALID_ID, MATCH_NOT_FOUND, ARTIFACT_NOT_FOUND, DISTR_ENVIRONMENT_NOT_AVAILABLE, DISTR_ENVIRONMENT_NOT_FOUND, DISTR_ENVIRONMENT_SENT_IS_INVALID, DISTR_ARTIFACT_NOT_FOUND, OVERLOAD, INVALID_TYPE, INVALID_VALUE, INVALID_INNER_TYPE, CSAR_NOT_FOUND, GROUP_INVALID_CONTENT, CANNOT_UPDATE_EXISTING_ENTITY, PROPERTY_NAME_ALREADY_EXISTS, INVALID_PROPERTY,; + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java new file mode 100644 index 0000000000..c4bbaf58f6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java @@ -0,0 +1,413 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; + +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.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +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.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.IComplexDefaultValue; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +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.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public abstract class AbstractOperation { + private static Logger log = LoggerFactory.getLogger(AbstractOperation.class.getName()); + @javax.annotation.Resource + protected TitanGenericDao titanGenericDao; + public static final String EMPTY_VALUE = null; + + protected Gson gson = new Gson(); + + @javax.annotation.Resource + protected ApplicationDataTypeCache applicationDataTypeCache; + + protected DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + protected Either addDefinitionToNodeType(SomeDefenition someDefinition, NodeTypeEnum nodeType, String nodeUniqueId, final GraphEdgeLabels edgeType, + Supplier dataBuilder, Supplier defNameGenerator) { + String defName = defNameGenerator.get(); + log.debug("Got {} {}", defName, someDefinition); + + SomeData someData = dataBuilder.get(); + + log.debug("Before adding {} to graph. data = {}", defName, someData); + + @SuppressWarnings("unchecked") + Either eitherSomeData = titanGenericDao.createNode(someData, (Class) someData.getClass()); + + log.debug("After adding {} to graph. status is = {}", defName, eitherSomeData); + + if (eitherSomeData.isRight()) { + TitanOperationStatus operationStatus = eitherSomeData.right().value(); + log.error("Failed to add {} to graph. status is {}", defName, operationStatus); + return Either.right(operationStatus); + } + UniqueIdData uniqueIdData = new UniqueIdData(nodeType, nodeUniqueId); + log.debug("Before associating {} to {}.", uniqueIdData, defName); + + Either eitherRelations = titanGenericDao.createRelation(uniqueIdData, eitherSomeData.left().value(), edgeType, null); + if (eitherRelations.isRight()) { + TitanOperationStatus operationStatus = eitherRelations.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("AddDefinitionToNodeType", "Failed to associate" + nodeType.getName() + " " + nodeUniqueId + "to " + defName + "in graph. status is " + operationStatus, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } + return Either.left(eitherSomeData.left().value()); + } + + protected TitanOperationStatus addDefinitionToNodeType(TitanVertex vertex, SomeDefenition someDefinition, NodeTypeEnum nodeType, String nodeUniqueId, final GraphEdgeLabels edgeType, + Supplier dataBuilder, Supplier defNameGenerator) { + String defName = defNameGenerator.get(); + log.debug("Got {} {}", defName, someDefinition); + + SomeData someData = dataBuilder.get(); + + log.debug("Before adding {} to graph. data = {}", defName, someData); + + @SuppressWarnings("unchecked") + Either eitherSomeData = titanGenericDao.createNode(someData); + + log.debug("After adding {} to graph. status is = {}", defName, eitherSomeData); + + if (eitherSomeData.isRight()) { + TitanOperationStatus operationStatus = eitherSomeData.right().value(); + log.error("Failed to add {} to graph. status is {}", defName, operationStatus); + return operationStatus; + } + + TitanOperationStatus relations = titanGenericDao.createEdge(vertex, eitherSomeData.left().value(), edgeType, null); + if (!relations.equals(TitanOperationStatus.OK)) { + TitanOperationStatus operationStatus = relations; + BeEcompErrorManager.getInstance().logInternalFlowError("AddDefinitionToNodeType", "Failed to associate" + nodeType.getName() + " " + nodeUniqueId + "to " + defName + "in graph. status is " + operationStatus, ErrorSeverity.ERROR); + return operationStatus; + } + return relations; + } + + interface NodeElementFetcher { + TitanOperationStatus findAllNodeElements(String nodeId, List listTofill); + } + + public TitanOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId, List elements, NodeElementFetcher singleNodeFetcher) { + + if (log.isTraceEnabled()) + log.trace("Going to fetch elements under resource {}", resourceId); + TitanOperationStatus resourceAttributesStatus = singleNodeFetcher.findAllNodeElements(resourceId, elements); + + if (resourceAttributesStatus != TitanOperationStatus.OK) { + return resourceAttributesStatus; + } + + Either, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, + ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (parentNodesStatus != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find parent elements of resource " + resourceId + ". status is " + parentNodesStatus, ErrorSeverity.ERROR); + return parentNodesStatus; + } + } + + if (parentNodes.isLeft()) { + ImmutablePair parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findAllResourceElementsDefinitionRecursively(parentUniqueId, elements, singleNodeFetcher); + + if (addParentIntStatus != TitanOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find all resource elements of resource " + parentUniqueId, ErrorSeverity.ERROR); + + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + } + + protected void handleTransactionCommitRollback(boolean inTransaction, Either result) { + if (!inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + public Either getElementType(Function> elementGetter, String uniqueId, boolean inTransaction) { + Either result = null; + try { + + Either ctResult = elementGetter.apply(uniqueId); + + if (ctResult.isRight()) { + TitanOperationStatus status = ctResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to retrieve information on element uniqueId:" + uniqueId + ". status is " + status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value())); + return result; + } + + result = Either.left(ctResult.left().value()); + + return result; + } finally { + handleTransactionCommitRollback(inTransaction, result); + + } + + } + + /** + * @param propertyDefinition + * @return + */ + + protected StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map dataTypes) { + + log.trace("Going to validate property type and value. {}", propertyDefinition); + + String propertyType = propertyDefinition.getType(); + String value = propertyDefinition.getDefaultValue(); + + ToscaPropertyType type = getType(propertyType); + + if (type == null) { + + DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType); + if (dataTypeDefinition == null) { + log.debug("The type {} of property cannot be found.", propertyType); + return StorageOperationStatus.INVALID_TYPE; + } + + StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes); + + return status; + + } + String innerType = null; + + Either checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema()); + if (checkInnerType.isRight()) { + return StorageOperationStatus.INVALID_TYPE; + } + innerType = checkInnerType.left().value(); + + log.trace("After validating property type {}", propertyType); + + boolean isValidProperty = isValidValue(type, value, innerType, dataTypes); + if (false == isValidProperty) { + log.info("The value {} of property from type {} is invalid", value, type); + return StorageOperationStatus.INVALID_VALUE; + } + + PropertyValueConverter converter = type.getConverter(); + + if (isEmptyValue(value)) { + log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE); + propertyDefinition.setDefaultValue(EMPTY_VALUE); + } else if (false == isEmptyValue(value)) { + String convertedValue = converter.convert(value, innerType, dataTypes); + propertyDefinition.setDefaultValue(convertedValue); + } + return StorageOperationStatus.OK; + } + + protected ToscaPropertyType getType(String propertyType) { + + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + return type; + + } + + protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map dataTypes) { + if (isEmptyValue(value)) { + return true; + } + + PropertyTypeValidator validator = type.getValidator(); + + boolean isValid = validator.isValid(value, innerType, dataTypes); + if (true == isValid) { + return true; + } else { + return false; + } + + } + + public boolean isEmptyValue(String value) { + if (value == null) { + return true; + } + return false; + } + + public boolean isNullParam(String value) { + if (value == null) { + return true; + } + return false; + } + + protected StorageOperationStatus validateAndUpdateComplexValue(IComplexDefaultValue propertyDefinition, String propertyType, + + String value, DataTypeDefinition dataTypeDefinition, Map dataTypes) { + + ImmutablePair validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes); + + if (validateResult.right.booleanValue() == false) { + log.debug("The value {} of property from type {} is invalid", value, propertyType); + return StorageOperationStatus.INVALID_VALUE; + } + + JsonElement jsonElement = validateResult.left; + + log.trace("Going to update value in property definition {} {}", propertyDefinition.getName(), (jsonElement != null ? jsonElement.toString() : null)); + + updateValue(propertyDefinition, jsonElement); + + return StorageOperationStatus.OK; + } + + protected void updateValue(IComplexDefaultValue propertyDefinition, JsonElement jsonElement) { + + propertyDefinition.setDefaultValue(getValueFromJsonElement(jsonElement)); + + } + + protected String getValueFromJsonElement(JsonElement jsonElement) { + String value = null; + + if (jsonElement == null || jsonElement.isJsonNull()) { + value = EMPTY_VALUE; + } else { + if (jsonElement.toString().isEmpty()) { + value = ""; + } else { + value = jsonElement.toString(); + } + } + + return value; + } + + protected Either getInnerType(ToscaPropertyType type, Supplier schemeGen) { + String innerType = null; + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + + SchemaDefinition def = schemeGen.get();// propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exists", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + return Either.left(innerType); + } + + /** + * Convert Constarint object to json in order to add it to the Graph + * + * @param constraints + * @return + */ + public List convertConstraintsToString(List constraints) { + + List result = null; + + if (constraints != null && false == constraints.isEmpty()) { + result = new ArrayList(); + for (PropertyConstraint propertyConstraint : constraints) { + String constraint = gson.toJson(propertyConstraint); + result.add(constraint); + } + + } + + return result; + } + + public List convertConstraints(List constraints) { + + if (constraints == null || constraints.size() == 0) { + return null; + } + + List list = new ArrayList(); + Type constraintType = new TypeToken() { + }.getType(); + + Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create(); + + for (String constraintJson : constraints) { + PropertyConstraint propertyConstraint = gson.fromJson(constraintJson, constraintType); + list.add(propertyConstraint); + } + + return list; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java new file mode 100644 index 0000000000..e2c7f369f1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java @@ -0,0 +1,960 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +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.elements.AdditionalInfoParameterDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.AdditionalInfoParameterData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.AutoPopulatingList.ElementFactory; + +import fj.data.Either; + +@Component("additional-information-operation") +public class AdditionalInformationOperation implements IAdditionalInformationOperation { + + public static final String EMPTY_VALUE = null; + public static final String PROPERTY = "property"; + + public AdditionalInformationOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(AdditionalInformationOperation.class.getName()); + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @Override + public Either addAdditionalInformationParameter( + NodeTypeEnum nodeType, String componentId, String key, String value) { + + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + + Either, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map parameters = parameterData.getParameters(); + if (parameters == null) { + parameters = new HashMap(); + parameterData.setParameters(parameters); + } + Map idToKey = parameterData.getIdToKey(); + if (idToKey == null) { + idToKey = new HashMap(); + parameterData.setIdToKey(idToKey); + } + + Integer lastCreatedCounter = parameterData.getAdditionalInfoParameterDataDefinition().getLastCreatedCounter(); + lastCreatedCounter++; + + if (parameters.containsKey(key)) { + log.debug("The key {} already exists under component {}", key, componentId); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + + idToKey.put(String.valueOf(lastCreatedCounter), key); + parameters.put(key, value); + parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter); + + Either updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, + "UpdateAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + return Either.right(status); + } + + AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, + parameters, idToKey, updateNode.left().value()); + + return Either.left(informationDefinition); + + } + + @Override + public Either updateAdditionalInformationParameter( + NodeTypeEnum nodeType, String componentId, String id, String key, String value) { + + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + + Either, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map parameters = parameterData.getParameters(); + Map idToKey = parameterData.getIdToKey(); + if (idToKey == null || false == idToKey.containsKey(id)) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + String origKey = idToKey.get(id); + + if (false == origKey.equals(key)) { + if (parameters.containsKey(key)) { + log.debug("The key {} already exists", key); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + String removed = parameters.remove(origKey); + log.trace("The key-value " + origKey + "=" + removed + " was removed from additionalInformation"); + } + parameters.put(key, value); + idToKey.put(id, key); + + Either updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, + "UpdateAdditionalInformationParameter", "additional information of resource " + componentId, + String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", + "additional information of resource " + componentId, String.valueOf(status)); + return Either.right(status); + } + + AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, + parameters, idToKey, updateNode.left().value()); + + return Either.left(informationDefinition); + + } + + @Override + public Either deleteAdditionalInformationParameter( + NodeTypeEnum nodeType, String componentId, String id) { + + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + + Either, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map parameters = parameterData.getParameters(); + Map idToKey = parameterData.getIdToKey(); + + if (idToKey == null || false == idToKey.containsKey(id)) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + String key = idToKey.get(id); + String removedKey = idToKey.remove(id); + String removedValue = parameters.remove(key); + log.trace("The key-value " + removedKey + "=" + removedValue + " was removed from additionalInformation"); + + Either updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, + "DeleteAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("DeleteAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + return Either.right(status); + } + + AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, + parameters, idToKey, updateNode.left().value()); + + return Either.left(informationDefinition); + + } + + private AdditionalInformationDefinition createInformationDefinitionFromNode(String resourceId, + Map parameters, Map idToKey, + AdditionalInfoParameterData additionalInfoParameterData) { + AdditionalInfoParameterDataDefinition dataDefinition = additionalInfoParameterData + .getAdditionalInfoParameterDataDefinition(); + + AdditionalInformationDefinition informationDefinition = new AdditionalInformationDefinition(dataDefinition, + resourceId, convertParameters(parameters, idToKey)); + return informationDefinition; + } + + private List convertParameters(Map parameters, + Map idToKey) { + + List list = new ArrayList(); + + if (parameters != null) { + for (Entry idToKeyEntry : idToKey.entrySet()) { + + String id = idToKeyEntry.getKey(); + String key = idToKeyEntry.getValue(); + + String value = parameters.get(key); + + AdditionalInfoParameterInfo parameterInfo = new AdditionalInfoParameterInfo(id, key, value); + list.add(parameterInfo); + } + + } + + return list; + } + + @Override + public Either addAdditionalInformationNode(NodeTypeEnum nodeType, + String componentId) { + + UniqueIdData from = new UniqueIdData(nodeType, componentId); + + String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId); + AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition(); + additionalInfoParameterDataDefinition.setUniqueId(uniqueId); + + AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData( + additionalInfoParameterDataDefinition, new HashMap(), new HashMap()); + + Either createNode = titanGenericDao + .createNode(additionalInfoParameterData, AdditionalInfoParameterData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedCreateNodeError, + "AddAdditionalInformationNode", + "additional information to " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, + String.valueOf(status)); + return Either.right(status); + } + + AdditionalInfoParameterData to = createNode.left().value(); + + Either createRelation = titanGenericDao.createRelation(from, to, + GraphEdgeLabels.ADDITIONAL_INFORMATION, null); + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + return Either.right(status); + } + + return Either.left(to); + } + + @Override + public Either addAdditionalInformationNode(NodeTypeEnum nodeType, + String componentId, TitanVertex metadataVertex) { + + String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId); + AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition(); + additionalInfoParameterDataDefinition.setUniqueId(uniqueId); + + AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData( + additionalInfoParameterDataDefinition, new HashMap(), new HashMap()); + + Either createNode = titanGenericDao.createNode(additionalInfoParameterData); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedCreateNodeError, + "AddAdditionalInformationNode", + "additional information to " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, + String.valueOf(status)); + return Either.right(status); + } + + TitanVertex additionalInfoVertex = createNode.left().value(); + + TitanOperationStatus createRelation = titanGenericDao.createEdge(metadataVertex, additionalInfoVertex, + GraphEdgeLabels.ADDITIONAL_INFORMATION, null); + + if (!createRelation.equals(TitanOperationStatus.OK)) { + return Either.right(createRelation); + } + return Either.left(additionalInfoVertex); + } + + public Either addAdditionalInformationNode( + NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters) { + + Either status = this.addAdditionalInformationNode(nodeType, + componentId); + + if (status.isRight()) { + return Either.right(status.right().value()); + } + + AdditionalInfoParameterData parameterData = status.left().value(); + + populateParameterNodeWithParameters(parameterData, parameters); + + Either updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + return Either.right(updateNode.right().value()); + } + + AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition( + updateNode.left().value(), componentId); + + return Either.left(informationDefinition); + } + + public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, + AdditionalInformationDefinition parameters, TitanVertex metadataVertex) { + + Either status = this.addAdditionalInformationNode(nodeType, componentId, + metadataVertex); + + if (status.isRight()) { + return status.right().value(); + } + TitanVertex additionalInfoVertex = status.left().value(); + + Map newProp = titanGenericDao.getProperties(additionalInfoVertex); + AdditionalInfoParameterData parameterData = GraphElementFactory.createElement( + NodeTypeEnum.AdditionalInfoParameters.getName(), GraphElementTypeEnum.Node, newProp, + AdditionalInfoParameterData.class); + + populateParameterNodeWithParameters(parameterData, parameters); + + TitanOperationStatus updateNode = titanGenericDao.updateVertex(parameterData, additionalInfoVertex); + + return updateNode; + } + + private void populateParameterNodeWithParameters(AdditionalInfoParameterData parameterData, + AdditionalInformationDefinition aiDefinition) { + + if (aiDefinition != null) { + + Integer lastCreatedCounter = aiDefinition.getLastCreatedCounter(); + parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter); + log.trace("Set last created counter of additional information to " + lastCreatedCounter); + + List parameters = aiDefinition.getParameters(); + if (parameters != null) { + + Map idToKey = new HashMap(); + Map parametersMap = new HashMap(); + for (AdditionalInfoParameterInfo additionalInfoParameterInfo : parameters) { + String uniqueId = additionalInfoParameterInfo.getUniqueId(); + String key = additionalInfoParameterInfo.getKey(); + String value = additionalInfoParameterInfo.getValue(); + + if (key != null && false == key.isEmpty()) { + idToKey.put(uniqueId, key); + parametersMap.put(key, value); + } + } + parameterData.setIdToKey(idToKey); + parameterData.setParameters(parametersMap); + } + } + + } + + @Override + public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, + List properties) { + + log.trace("Going to fetch additional information under resource " + uniqueId); + TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Resource, + uniqueId, properties); + + if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) { + return resourceCapabilitiesStatus; + } + + Either, TitanOperationStatus> parentNodes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (false == parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) { + log.error("Failed to find parent additional information of resource " + uniqueId + ". status is " + + parentNodesStatus); + return parentNodesStatus; + } + } + + if (parentNodes.isLeft()) { + ImmutablePair parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findResourceAllAdditionalInformationRecursively(parentUniqueId, + properties); + + if (addParentIntStatus != TitanOperationStatus.OK) { + log.error("Failed to find all resource additional information of resource " + parentUniqueId); + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + + } + + @Override + public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, + List properties) { + + log.trace("Going to fetch additional information under service " + uniqueId); + TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Service, + uniqueId, properties); + + if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) { + return resourceCapabilitiesStatus; + } + + Either, TitanOperationStatus> parentNodes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), uniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Service, ServiceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (false == parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) { + log.error("Failed to find parent additional information of resource " + uniqueId + ". status is " + + parentNodesStatus); + return parentNodesStatus; + } + } + + if (parentNodes.isLeft()) { + ImmutablePair parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findServiceAllAdditionalInformationRecursively(parentUniqueId, + properties); + + if (addParentIntStatus != TitanOperationStatus.OK) { + log.error("Failed to find all resource additional information of resource " + parentUniqueId); + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + + } + + private TitanOperationStatus findAdditionalInformationOfNode(NodeTypeEnum nodeType, String uniqueId, + List properties) { + + Either, TitanOperationStatus> childNode = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.ADDITIONAL_INFORMATION, + NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class); + + if (childNode.isRight()) { + TitanOperationStatus status = childNode.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return status; + } + + ImmutablePair immutablePair = childNode.left().value(); + AdditionalInfoParameterData propertyData = immutablePair.getKey(); + + Map parameters = propertyData.getParameters(); + if (parameters != null && false == parameters.isEmpty()) { + AdditionalInformationDefinition additionalInfoDef = this + .convertAdditionalInformationDataToDefinition(propertyData, uniqueId); + properties.add(additionalInfoDef); + } + + return TitanOperationStatus.OK; + + } + + private AdditionalInformationDefinition convertAdditionalInformationDataToDefinition( + AdditionalInfoParameterData additionalInfoData, String uniqueId) { + + Map parameters = additionalInfoData.getParameters(); + Map idToKey = additionalInfoData.getIdToKey(); + + AdditionalInformationDefinition definition = new AdditionalInformationDefinition( + additionalInfoData.getAdditionalInfoParameterDataDefinition(), uniqueId, + convertParameters(parameters, idToKey)); + return definition; + } + + @Override + public Either createAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction) { + + Either result = null; + + try { + + Either either = this + .addAdditionalInformationParameter(nodeType, resourceId, key, value); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + log.debug("Failed to add additional information property {} to component {}. Status is {}", key, resourceId, status); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, + "additional information of " + nodeType.getName() + " " + resourceId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("CreateAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + resourceId, String.valueOf(status)); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + } finally { + commitOrRollback(inTransaction, result); + } + + } + + @Override + public Either updateAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction) { + + Either result = null; + + try { + + Either either = this + .updateAdditionalInformationParameter(nodeType, resourceId, id, key, value); + + if (either.isRight()) { + log.info("Failed to update additional information property " + key + " to component " + resourceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value())); + } else { + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + + } + + @Override + public Either deleteAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) { + + Either result = null; + + try { + + Either either = this + .deleteAdditionalInformationParameter(nodeType, resourceId, id); + + if (either.isRight()) { + log.error("Failed to delete additional information id " + id + " to component " + resourceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value())); + } else { + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + + } + + @Override + public Either getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, + String resourceId, boolean inTransaction) { + + Either result = null; + + try { + + Either either = this.getNumberOfParameters(nodeType, resourceId); + + if (either.isRight()) { + log.error("Failed to get the number of additional information properties in component " + resourceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value())); + } else { + Integer counter = either.left().value(); + result = Either.left(counter); + } + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either getNumberOfParameters(NodeTypeEnum nodeType, String resourceId) { + + Either, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map parameters = parameterData.getParameters(); + + Integer counter = 0; + if (parameters != null) { + counter = parameters.size(); + } + + return Either.left(counter); + + } + + @Override + public Either getAdditionalInformationParameter( + NodeTypeEnum nodeType, String componentId, String id) { + + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + + Either, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map parameters = parameterData.getParameters(); + Map idToKey = parameterData.getIdToKey(); + + if (idToKey == null || false == idToKey.containsKey(id)) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + String key = idToKey.get(id); + String value = parameters.get(key); + + log.trace("The key-value " + key + "=" + value + " was retrieved for id " + id); + + Either updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedRetrieveNodeError, + "GetAdditionnalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + } + return Either.right(status); + } + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(id, key, value); + + return Either.left(additionalInfoParameterInfo); + + } + + @Override + public Either getAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String componentId, boolean ignoreVerification) { + + if (false == ignoreVerification) { + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + } + + Either, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedRetrieveNodeError, + "GetAdditionnalInformationParameters", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameters", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + } + return Either.right(status); + } + + ImmutablePair immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map parameters = parameterData.getParameters(); + Map idToKey = parameterData.getIdToKey(); + + AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, + parameters, idToKey, parameterData); + + return Either.left(informationDefinition); + + } + + @Override + public Either getAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction) { + + Either result = null; + + try { + + Either either = this + .getAllAdditionalInformationParameters(nodeType, resourceId, ignoreVerification); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + + } + + private void commitOrRollback(boolean inTransaction, Either result) { + + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + private void commitOrRollbackTx(TitanTransaction tx, boolean inTransaction, + Either result) { + + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + tx.rollback(); + } else { + log.debug("Going to execute commit on graph."); + tx.commit(); + } + } + } + + @Override + public Either getAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) { + + Either result = null; + + try { + + Either either = this + .getAdditionalInformationParameter(nodeType, resourceId, id); + + if (either.isRight()) { + log.error("Failed to fetch additional information property with id " + id + " of component " + + resourceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value())); + } else { + AdditionalInfoParameterInfo additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + } + + @Override + public Either deleteAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean inTransaction) { + + Either result = null; + + try { + + Either, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.OK); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedDeleteNodeError, + "DeleteAdditionalInformationNode", + "additional information of " + nodeType.getName() + " " + resourceId, + String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", + "additional information of " + nodeType.getName() + " " + resourceId, + String.valueOf(status)); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + return result; + } + + ImmutablePair value = getResult.left().value(); + AdditionalInfoParameterData parameterData = value.getLeft(); + + Either deleteNodeRes = titanGenericDao + .deleteNode(parameterData, AdditionalInfoParameterData.class); + if (deleteNodeRes.isRight()) { + TitanOperationStatus status = getResult.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedDeleteNodeError, + "DeleteAdditionalInformationNode", (String) parameterData.getUniqueId(), + String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", + (String) parameterData.getUniqueId(), String.valueOf(status)); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition( + deleteNodeRes.left().value(), resourceId); + + result = Either.left(informationDefinition); + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + } + + private TitanOperationStatus verifyNodeTypeVsComponent(NodeTypeEnum nodeType, String componentId) { + Either vertexByProperty = titanGenericDao + .getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (vertexByProperty.isRight()) { + TitanOperationStatus status = vertexByProperty.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return status; + } else { + Vertex v = vertexByProperty.left().value(); + String label = (String) v.property(GraphPropertiesDictionary.LABEL.getProperty()).value(); + if (label != null) { + if (false == label.equals(nodeType.getName())) { + log.debug("The node type {} is not appropriate to component {}", nodeType, componentId); + return TitanOperationStatus.INVALID_ID; + } + } else { + log.debug("The node type {} with id {} does not have a label property.", nodeType, componentId); + return TitanOperationStatus.INVALID_ID; + } + } + return TitanOperationStatus.OK; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AllOperationsUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AllOperationsUtil.java new file mode 100644 index 0000000000..c005176238 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AllOperationsUtil.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.be.model.operations.impl; + +import org.springframework.stereotype.Component; + +@Component("all-operations") +public class AllOperationsUtil { + + @javax.annotation.Resource + private PropertyOperation propertyOperation; + + @javax.annotation.Resource + private RequirementOperation requirementOperation; + + @javax.annotation.Resource + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource + private ResourceOperation resourceOperation; + + public PropertyOperation getPropertyOperation() { + return propertyOperation; + } + + public RequirementOperation getRequirementOperation() { + return requirementOperation; + } + + public CapabilityOperation getCapabilityOperation() { + return capabilityOperation; + } + + public ResourceOperation getResourceOperation() { + return resourceOperation; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java new file mode 100644 index 0000000000..a4f4bebd5a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java @@ -0,0 +1,1202 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.thinkaurelius.titan.core.TitanTransaction; +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.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +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.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.HeatParameterData; +import org.openecomp.sdc.be.resources.data.HeatParameterValueData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanGraph; +//import com.tinkerpop.blueprints.Direction; +//import com.tinkerpop.blueprints.Edge; +//import com.tinkerpop.blueprints.Vertex; +//import com.tinkerpop.blueprints.util.ElementHelper; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@Component("artifact-operation") +public class ArtifactOperation implements IArtifactOperation { + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @javax.annotation.Resource + private HeatParametersOperation heatParametersOperation; + + @javax.annotation.Resource + private GroupOperation groupOperation; + + private static Logger log = LoggerFactory.getLogger(ArtifactOperation.class.getName()); + + public ArtifactOperation() { + super(); + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + public HeatParametersOperation getHeatParametersOperation() { + return heatParametersOperation; + } + + public void setHeatParametersOperation(HeatParametersOperation heatParametersOperation) { + this.heatParametersOperation = heatParametersOperation; + } + + @Override + public Either addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, boolean inTransaction) { + + Either status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist); + + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.debug("Failed to add artifact {} to {} {}", artifactInfo.getArtifactName(), type, parentId); + return Either.right(status.right().value()); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + ArtifactData artifactData = status.left().value(); + + ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData); + + log.debug("The returned ArtifactDefintion is {}", artifactDefResult); + return Either.left(artifactDefResult); + } + + } + + @Override + public StorageOperationStatus addArifactToComponent(TitanVertex artifactInfo, TitanVertex parentVertex, String label) { + + // save logical artifact ref name on edge as property + Map properties = new HashMap(); + properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), label); + String groupInfo = (String) titanGenericDao.getProperty(artifactInfo, GraphPropertiesDictionary.ARTIFACT_GROUP_TYPE.getProperty()); + if (groupInfo != null) + properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), groupInfo); + TitanOperationStatus relation = titanGenericDao.createEdge(parentVertex, artifactInfo, GraphEdgeLabels.ARTIFACT_REF, properties); + if (!relation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create relation in graph from id {} to new artifact {}", parentVertex, label); + return DaoStatusConverter.convertTitanStatusToStorageStatus(relation); + } + return StorageOperationStatus.OK; + + } + + @Override + public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, TitanVertex parentVertex) { + + StorageOperationStatus status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist, parentVertex); + + if (status.equals(StorageOperationStatus.OK)) { + log.debug("Failed to add artifact {} {} to {}", artifactInfo.getArtifactName(), type, parentId); + } + return status; + } + + private StorageOperationStatus addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist, TitanVertex parentVertex) { + + if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) { + String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel()); + artifactInfo.setUniqueId(uniqueId); + } + + if (validateParentType(type) == false) { + return StorageOperationStatus.GENERAL_ERROR; + } + + ArtifactData artifactData = new ArtifactData(artifactInfo); + + Either existArtifact = titanGenericDao.getVertexByProperty(artifactData.getUniqueIdKey(), artifactData.getUniqueId()); + if (existArtifact.isRight()) { + if (existArtifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + // create new node + log.debug("Before adding artifact to graph {}", artifactData); + if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty()) + updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion()); + Either createNodeResult = titanGenericDao.createNode(artifactData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedCreateNodeError, "Failed to add artifact " + artifactData.getArtifactDataDefinition().getArtifactName() + " to graph. status is " + operationStatus, + artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus)); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus)); + return DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus); + } + + // add heat parameters + if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef); + if (addPropertiesStatus != StorageOperationStatus.OK) { + log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName()); + return addPropertiesStatus; + } + } + + } else { + log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(existArtifact.right().value()); + } + } else if (failIfexist) { + log.debug("Artifact {} already exist", artifactData.getUniqueId()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ALREADY_EXIST); + } + + // save logical artifact ref name on edge as property + Map properties = new HashMap(); + properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel()); + if (artifactInfo.getArtifactGroupType() != null) + properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType()); + TitanOperationStatus relation = titanGenericDao.createEdge(parentVertex, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties); + if (!relation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create relation in graph for id {} to new artifact", id); + return DaoStatusConverter.convertTitanStatusToStorageStatus(relation); + } + + return StorageOperationStatus.OK; + } + + private Either addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist) { + + if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) { + String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel()); + artifactInfo.setUniqueId(uniqueId); + } + + if (validateParentType(type) == false) { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + ArtifactData artifactData = new ArtifactData(artifactInfo); + + Either existArtifact = titanGenericDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class); + if (existArtifact.isRight()) { + if (existArtifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + // create new node + log.debug("Before adding artifact to graph {}", artifactData); + if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty()) + updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion()); + Either createNodeResult = titanGenericDao.createNode(artifactData, ArtifactData.class); + log.debug("After adding artifact to graph {}", artifactData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedCreateNodeError, "Failed to add artifact " + artifactData.getArtifactDataDefinition().getArtifactName() + " to graph. status is " + operationStatus, + artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus)); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus)); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus)); + } + artifactData = createNodeResult.left().value(); + + // add heat parameters + if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef); + if (addPropertiesStatus != StorageOperationStatus.OK) { + log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName()); + return Either.right(addPropertiesStatus); + } + } + + } else { + log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(existArtifact.right().value())); + } + } else if (failIfexist) { + log.debug("Artifact {} already exist", artifactData.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ALREADY_EXIST)); + } else { + artifactData = existArtifact.left().value(); + } + + UniqueIdData parent = new UniqueIdData(type, id); + + // save logical artifact ref name on edge as property + Map properties = new HashMap(); + properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel()); + if (artifactInfo.getArtifactGroupType() != null) + properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType()); + Either relation = titanGenericDao.createRelation(parent, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties); + if (relation.isRight()) { + log.debug("Failed to create relation in graph for id {} to new artifact", id); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(relation.right().value())); + } + + return Either.left(artifactData); + } + + private boolean validateParentType(NodeTypeEnum type) { + boolean isValid = false; + switch (type) { + case Resource: + case InterfaceOperation: + case Service: + case ResourceInstance: + isValid = true; + break; + default: + log.debug("Not supported node type for artifact relation : {}", type); + } + return isValid; + } + + protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactData artifactDefResult) { + log.debug("The object returned after create property is {}", artifactDefResult); + + ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult.getArtifactDataDefinition()); + List parameters = new ArrayList(); + StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters); + if ((heatParametersOfNode.equals(StorageOperationStatus.OK)) && !parameters.isEmpty()) { + propertyDefResult.setHeatParameters(parameters); + } + return propertyDefResult; + } + + @Override + public Either updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction) { + Either status = updateArtifactOnGraph(artifactInfo, artifactId, type, id); + + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + if (log.isDebugEnabled()){ + log.debug("Failed to update artifact {} of {} {}. Status is {}", artifactId, type.getName(), id, status.right().value()); + } + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, "Failed to update artifact " + artifactId + " of " + type.getName() + " " + id + ". status is" + status.right().value(), artifactId, + String.valueOf(status.right().value())); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactId, String.valueOf(status.right().value())); + return Either.right(status.right().value()); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + ArtifactData artifactData = status.left().value(); + + ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData); + log.debug("The returned ArtifactDefintion is {}", artifactDefResult); + return Either.left(artifactDefResult); + } + } + + @Override + public Either updateArifactDefinition(ArtifactDefinition artifactInfo, boolean inTransaction) { + Either status = updateArifactDataDefinition(artifactInfo); + + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.debug("Failed to update artifact {}", artifactInfo.getUniqueId()); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, "Failed to update artifact " + artifactInfo.getUniqueId() + ". status is" + status.right().value(), artifactInfo.getUniqueId(), + String.valueOf(status.right().value())); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getUniqueId(), String.valueOf(status.right().value())); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + ArtifactData artifactData = status.left().value(); + + ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData); + log.debug("The returned ArtifactDefintion is {}", artifactDefResult); + return Either.left(artifactDefResult); + } + } + + private Either updateArifactDataDefinition(ArtifactDefinition artifactInfo) { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(graph.right().value()); + } + + ArtifactData artifactData = new ArtifactData(artifactInfo); + + Either status = titanGenericDao.updateNode(artifactData, ArtifactData.class); + + if (status.isRight()) { + return Either.right(status.right().value()); + + } + return Either.left(status.left().value()); + } + + @Override + public Either removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact, boolean inTransaction) { + Either status = removeArtifactOnGraph(id, artifactId, type, id, deleteMandatoryArtifact); + + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.debug("Failed to delete artifact {} of resource {}", artifactId, id); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedDeleteNodeError, "Failed to delete artifact " + artifactId + " of resource " + id, artifactId, String.valueOf(status.right().value())); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value())); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + ArtifactData artifactData = status.left().value(); + + ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData); + log.debug("The returned ArtifactDefintion is {}", artifactDefResult); + return Either.left(artifactDefResult); + } + } + + public Either updateToscaArtifactNameOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id) { + return updateArtifactOnGraph(artifactInfo, artifactId, type, id); + } + + @SuppressWarnings("null") + private Either updateArtifactOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id) { + + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + + TitanGraph tGraph = graph.left().value(); + + @SuppressWarnings("unchecked") + Iterable verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices(); + Iterator iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No artifact node for id = {}", artifactId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + TitanVertex artifactV = iterator.next(); + + Iterator iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + + int edgeCount = 0; + Edge edgeFromTo = null; + while (iterEdge.hasNext()) { + Edge edge = iterEdge.next(); + Vertex vertexFrom = edge.outVertex(); + String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type)); + if (id.equals(vertexId)) { + edgeFromTo = edge; + } + ++edgeCount; + } + + ArtifactData artifactData = new ArtifactData(artifactInfo); + if (edgeFromTo == null) { + log.debug("No relation between artifact = {} and node with id = {}", artifactId, id); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Either setRelevantHeatParamIdRes = null; + if (edgeCount > 1) { + // need to remove relation, create new node + log.debug("artifactRef have more connection. Need to clone node"); + log.debug("remove edge {}", edgeFromTo); + edgeFromTo.remove(); + // update resource id in new artifact node + String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel()); + artifactInfo.setUniqueId(uniqueId); + // update UUID and artifact version + String oldChecksum = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty())); + String oldVersion = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty())); + updateUUID(artifactInfo, oldChecksum, oldVersion); + log.debug("try to create new artifact ref node for id {}", uniqueId); + Either addedArtifactRes = addArtifactToGraph(artifactInfo, id, type, true); + + if (addedArtifactRes.isLeft()) { + // remove all relations between groups to the old artifact + // add relation between the same groups to the new artifact + StorageOperationStatus reassociateGroupsFromArtifact = groupOperation.dissociateAndAssociateGroupsFromArtifact(id, type, artifactId, addedArtifactRes.left().value(), true); + if (reassociateGroupsFromArtifact != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("UpdateArtifact", "Failed to reassociate groups to the new artifact", ErrorSeverity.ERROR); + return Either.right(reassociateGroupsFromArtifact); + } + // If artifact is heat env + if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + ArtifactData addedArtifact = addedArtifactRes.left().value(); + String newArtifactUniqueId = (String) addedArtifact.getUniqueId(); + Either updateResult = null; + + setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo); + if (setRelevantHeatParamIdRes.isRight()) { + log.error("Failed to set relevant id to heat parameters for heat env artifact " + artifactInfo.getUniqueId() + ". Status is " + setRelevantHeatParamIdRes.right().value()); + return Either.right(setRelevantHeatParamIdRes.right().value()); + } + for (HeatParameterDefinition heatEnvParam : artifactInfo.getHeatParameters()) { + updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, newArtifactUniqueId, id, artifactInfo.getArtifactLabel()); + if (updateResult.isRight()) { + log.error("Failed to update heat parameter " + heatEnvParam.getName() + ". Status is " + updateResult.right().value()); + return Either.right(updateResult.right().value()); + } + } + + Iterator iterEdgeGeneratedFrom = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty()); + + if (!iterEdgeGeneratedFrom.hasNext()) { + log.error("No heat artifact node for id = " + artifactId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Edge edgeToHeat = iterEdgeGeneratedFrom.next(); + Vertex vertexIn = edgeToHeat.inVertex(); + String generatedFromArtifactId = vertexIn.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef)); + UniqueIdData generatedFromArtifactNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, generatedFromArtifactId); + Either createRelationToGeneratedFromArtifactRes = titanGenericDao.createRelation(addedArtifact, generatedFromArtifactNode, GraphEdgeLabels.GENERATED_FROM, null); + if (createRelationToGeneratedFromArtifactRes.isRight()) { + log.error("Failed to create relation from heat_env " + addedArtifact.getUniqueId() + " to heat " + generatedFromArtifactNode); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createRelationToGeneratedFromArtifactRes.right().value())); + } + } + } + return addedArtifactRes; + + } else { + if (edgeCount == 1) { + String oldChecksum = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty())); + String oldVersion = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty())); + updateUUID(artifactInfo, oldChecksum, oldVersion); + // update exist + Either updatedArtifact = titanGenericDao.updateNode(artifactData, ArtifactData.class); + if (updatedArtifact.isRight()) { + log.debug("failed to update artifact node for id {}", artifactData.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updatedArtifact.right().value())); + } + + if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + Either updateResult = null; + String artifactUniqueId = artifactInfo.getUniqueId(); + setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo); + if (setRelevantHeatParamIdRes.isRight()) { + log.error("Failed to set relevant id to heat parameters for heat env artifact {}. Status is {}", artifactInfo.getUniqueId(), setRelevantHeatParamIdRes.right().value()); + return Either.right(setRelevantHeatParamIdRes.right().value()); + } + for (HeatParameterDefinition heatEnvParam : artifactInfo.getHeatParameters()) { + updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, artifactUniqueId, id, artifactInfo.getArtifactLabel()); + if (updateResult.isRight()) { + log.error("Failed to update heat parameter " + heatEnvParam.getName() + ". Status is " + updateResult.right().value()); + return Either.right(updateResult.right().value()); + } + } + } else { + if (artifactData.getArtifactDataDefinition().getArtifactChecksum() == null) { + // update heat parameters only if it is not heat env + if (artifactInfo.getGeneratedFromId() == null) { + StorageOperationStatus operationStatus = heatParametersOperation.updateHeatParameters(artifactInfo.getHeatParameters()); + if (operationStatus != StorageOperationStatus.OK) { + return Either.right(operationStatus); + } + } + } else { + Either, StorageOperationStatus> deleteParameters = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactInfo.getUniqueId()); + if (deleteParameters.isRight()) { + log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + StorageOperationStatus addParameters = heatParametersOperation.addPropertiesToGraph(artifactInfo.getHeatParameters(), artifactId, NodeTypeEnum.ArtifactRef); + if (!addParameters.equals(StorageOperationStatus.OK)) { + log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + } + + return Either.left(updatedArtifact.left().value()); + } else { + log.debug("No relevent edges for artifact = {}", artifactId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + } + + private Either setRelevantHeatParamId(TitanVertex artifactV, ArtifactDefinition artifactInfo) { + + Map heatParametersHM = new HashMap(); + + Iterator iterHeat = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty()); + if (!iterHeat.hasNext()) { + log.debug("No edges with label GENERATED_FROM for the node {}", artifactInfo.getUniqueId()); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Edge heat = iterHeat.next(); + Vertex heatVertex = heat.inVertex(); + String heatUniqueId = (String) heatVertex.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef)); + + Either>, TitanOperationStatus> getHeatParametersRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatUniqueId, GraphEdgeLabels.HEAT_PARAMETER, + NodeTypeEnum.HeatParameter, HeatParameterData.class); + if (getHeatParametersRes.isRight()) { + log.debug("No heat parameters for heat artifact {}", heatUniqueId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + List> heatParameters = getHeatParametersRes.left().value(); + if (heatParameters == null) { + log.debug("No heat parameters for heat artifact {}", heatUniqueId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + for (ImmutablePair heatParamEdge : heatParameters) { + HeatParameterData heatParam = heatParamEdge.getLeft(); + heatParametersHM.put(heatParam.getName(), (String) heatParam.getUniqueId()); + } + String curName = null; + for (HeatParameterDefinition heatEnvParam : artifactInfo.getHeatParameters()) { + curName = heatEnvParam.getName(); + if (heatParametersHM.containsKey(curName)) { + heatEnvParam.setUniqueId(heatParametersHM.get(curName)); + } + } + return Either.left(true); + } + + public Either getParentsOfArtifact(String artifactId, NodeTypeEnum type) { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices(); + Iterator iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No artifact node for id = {}", artifactId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Vertex artifactV = iterator.next(); + Iterator iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + int edgeCount = 0; + while (iterEdge.hasNext()) { + Edge edge = iterEdge.next(); + ++edgeCount; + } + return Either.left(edgeCount); + } + + public Either removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type, String id2, boolean deleteMandatoryArtifact) { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(graph.right().value()); + } + + TitanGraph tGraph = graph.left().value(); + Either artifactData = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class); + if (artifactData.isRight()) { + log.debug("Failed to retrieve artifact for id = {}", artifactId); + return Either.right(artifactData.right().value()); + } + ArtifactDataDefinition artifactDefinition = artifactData.left().value().getArtifactDataDefinition(); + boolean isMandatory = false; + if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) { + // return Either.left(artifactData.left().value()); + isMandatory = true; + } + + @SuppressWarnings("unchecked") + Iterable verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices(); + Iterator iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No artifact node for id = {}", artifactId); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + Vertex artifactV = iterator.next(); + Iterator iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + int edgeCount = 0; + Edge edgeFromTo = null; + while (iterEdge.hasNext()) { + Edge edge = iterEdge.next(); + Vertex vertexFrom = edge.outVertex(); + String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type)); + if (id.equals(vertexId)) { + edgeFromTo = edge; + } + ++edgeCount; + } + if (edgeFromTo == null) { + log.debug("No relation between artifact = {} and node with id = {}", artifactId, id); + return Either.right(TitanOperationStatus.GENERAL_ERROR); + } + + // need to remove relation from resource/interface + + log.debug("remove edge {}", edgeFromTo); + if (!isMandatory || (isMandatory && edgeCount > 1)) { + edgeFromTo.remove(); + } + + // delete edges from all groups under the component id which related to + // this artifact. + // Also in case it is a mandatory artifact. + Either, TitanOperationStatus> dissociateAllGroups = groupOperation.dissociateAllGroupsFromArtifactOnGraph(id, type, artifactId); + if (dissociateAllGroups.isRight()) { + TitanOperationStatus status = dissociateAllGroups.right().value(); + if (status != TitanOperationStatus.NOT_FOUND && status != TitanOperationStatus.OK) { + return Either.right(status); + } + } + + if (edgeCount == 1) { + // remove artifactRef node + log.debug("Remove artifactRef node from graph"); + Either, StorageOperationStatus> deleteStatus = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId); + if (deleteStatus.isRight()) { + log.error("failed to delete heat parameters of artifact " + artifactId); + return Either.right(TitanOperationStatus.GENERAL_ERROR); + } + + StorageOperationStatus deleteValuesStatus = heatParametersOperation.deleteAllHeatValuesAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId); + if (!deleteValuesStatus.equals(StorageOperationStatus.OK)) { + log.error("failed to delete heat values of artifact " + artifactId); + return Either.right(TitanOperationStatus.GENERAL_ERROR); + } + if (!isMandatory) { + artifactV.remove(); + } + } else { + log.debug("artifactRef have more connection. ArtifactRef node will not be removed "); + } + + return Either.left(artifactData.left().value()); + + } + + /** + * + * @param parentId + * @param parentType + * @param inTransaction + * @return + */ + public Either, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction) { + Either, StorageOperationStatus> result = null; + try { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Failed to work with graph {}", graph.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices(); + if (vertices == null) { + log.debug("No nodes for type {} for id = {}", parentType, parentId); + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + Iterator iterator = vertices.iterator(); + + Map artifactMap = new HashMap(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + Iterator iteratorEdge = vertex.edges(Direction.OUT, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + + if (iteratorEdge != null) { + + while (iteratorEdge.hasNext()) { + Edge edge = iteratorEdge.next(); + + Vertex artifactV = edge.inVertex(); + + Map properties = this.titanGenericDao.getProperties(artifactV); + ArtifactData artifact = GraphElementFactory.createElement(NodeTypeEnum.ArtifactRef.getName(), GraphElementTypeEnum.Node, properties, ArtifactData.class); + if (artifact != null) { + + ArtifactDefinition artifactDefinition = new ArtifactDefinition(artifact.getArtifactDataDefinition()); + List heatParams = new ArrayList(); + StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId(), heatParams); + if (!heatParametersStatus.equals(StorageOperationStatus.OK)) { + log.debug("failed to get heat parameters for node {} {}", parentType.getName(), parentId); + return Either.right(heatParametersStatus); + } + if (!heatParams.isEmpty()) { + artifactDefinition.setHeatParameters(heatParams); + } + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + log.debug("Artifact was added to list {}", artifact.getUniqueId()); + } + } + } + } + result = Either.left(artifactMap); + return result; + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + + } + + public Either, StorageOperationStatus> getArtifactsVertecies(String parentId, NodeTypeEnum parentType, boolean inTransaction) { + Either, StorageOperationStatus> result = null; + try { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Failed to work with graph {}", graph.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices(); + if (vertices == null) { + log.debug("No nodes for type {} for id = {}", parentType, parentId); + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + Iterator iterator = vertices.iterator(); + + Map artifactMap = new HashMap(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + Iterator iteratorEdge = vertex.edges(Direction.OUT, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + + if (iteratorEdge != null) { + + while (iteratorEdge.hasNext()) { + Edge edge = iteratorEdge.next(); + + TitanVertex artifactV = (TitanVertex) edge.inVertex(); + String label = (String) titanGenericDao.getProperty(artifactV, GraphPropertiesDictionary.ARTIFACT_LABEL.getProperty()); + artifactMap.put(label, artifactV); + log.debug("Artifact was added to list {}", label); + } + } + } + result = Either.left(artifactMap); + return result; + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + + } + + @Override + public Either getArtifactById(String id, boolean inTransaction) { + Either result = null; + try { + Either artifact = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), id, ArtifactData.class); + if (artifact.isRight()) { + if (artifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + result = Either.right(StorageOperationStatus.ARTIFACT_NOT_FOUND); + } else { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(artifact.right().value())); + } + return result; + } + ArtifactData artifactData = artifact.left().value(); + + ArtifactDefinition artifactDef = new ArtifactDefinition(artifactData.getArtifactDataDefinition()); + List heatParams = new ArrayList(); + StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDef.getUniqueId(), heatParams); + if (!heatParametersStatus.equals(StorageOperationStatus.OK)) { + log.debug("failed to get heat parameters for artifact {}", id); + return Either.right(heatParametersStatus); + } + if (!heatParams.isEmpty()) { + artifactDef.setHeatParameters(heatParams); + } + + Either, TitanOperationStatus> generatedFromArtifact = titanGenericDao.getChild(artifactData.getUniqueIdKey(), (String) artifactData.getUniqueId(), GraphEdgeLabels.GENERATED_FROM, + NodeTypeEnum.ArtifactRef, ArtifactData.class); + if (generatedFromArtifact.isLeft()) { + ImmutablePair pair = generatedFromArtifact.left().value(); + String generatedFromId = (String) pair.left.getUniqueId(); + log.debug("artifact {} is generated from {}.", artifactData.getUniqueId(), generatedFromId); + artifactDef.setGeneratedFromId(generatedFromId); + Either, StorageOperationStatus> heatParamsForEnv = getHeatParamsForEnv(artifactDef); + if (heatParamsForEnv.isRight()) { + log.debug("failed to get heat parameters values for heat artifact {}", artifactDef.getUniqueId()); + return Either.right(heatParamsForEnv.right().value()); + } else { + artifactDef.setHeatParameters(heatParamsForEnv.left().value()); + } + } + + result = Either.left(artifactDef); + return result; + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + } + + public Either, StorageOperationStatus> getHeatParamsForEnv(ArtifactDefinition heatEnvArtifact) { + + List heatParams = new ArrayList(); + StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, heatEnvArtifact.getGeneratedFromId(), heatParams); + if (!heatParametersStatus.equals(StorageOperationStatus.OK)) { + log.debug("failed to get heat parameters for node {}", heatEnvArtifact.getGeneratedFromId()); + return Either.right(heatParametersStatus); + } + if (!heatParams.isEmpty()) { + + Map heatValuesMap = new HashMap(); + Either>, TitanOperationStatus> heatEnvValuesWithEdges = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), heatEnvArtifact.getUniqueId(), + GraphEdgeLabels.PARAMETER_VALUE, NodeTypeEnum.HeatParameterValue, HeatParameterValueData.class); + + if (heatEnvValuesWithEdges.isRight() && !heatEnvValuesWithEdges.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = heatEnvValuesWithEdges.right().value(); + if (!status.equals(TitanOperationStatus.NOT_FOUND)) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } else if (heatEnvValuesWithEdges.isLeft()) { + for (ImmutablePair pair : heatEnvValuesWithEdges.left().value()) { + HeatParameterValueData parameterValue = pair.left; + Object heatParameterName = pair.right.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + heatValuesMap.put((String) heatParameterName, parameterValue); + } + } + + for (HeatParameterDefinition parameter : heatParams) { + if (parameter.getCurrentValue() != null) { + if ("number".equals(parameter.getType())) { + parameter.setDefaultValue(new BigDecimal(parameter.getCurrentValue()).toPlainString()); + } else { + parameter.setDefaultValue(parameter.getCurrentValue()); + } + } + HeatParameterValueData heatParameterValueData = heatValuesMap.get(parameter.getName()); + if (heatParameterValueData != null && heatParameterValueData.getValue() != null) { + if ("number".equals(parameter.getType())) { + parameter.setCurrentValue(new BigDecimal(heatParameterValueData.getValue()).toPlainString()); + } else { + parameter.setCurrentValue(heatParameterValueData.getValue()); + } + parameter.setUniqueId((String) heatParameterValueData.getUniqueId()); + + } + } + } + + return Either.left(heatParams); + + } + + @Override + public Either, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction, String groupType) { + + Either, StorageOperationStatus> result = null; + try { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Failed to work with graph {}", graph.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices(); + if (vertices == null || vertices.iterator() == null || false == vertices.iterator().hasNext()) { + log.debug("No nodes for type {} for id = {}", parentType, parentId); + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + + Iterator iterator = vertices.iterator(); + Vertex vertex = iterator.next(); + + Map edgeProperties = null; + if (groupType != null) { + edgeProperties = new HashMap<>(); + edgeProperties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), groupType); + } + Either>, TitanOperationStatus> childrenByEdgeCriteria = titanGenericDao.getChildrenByEdgeCriteria(vertex, parentId, GraphEdgeLabels.ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class, + edgeProperties); + + if (childrenByEdgeCriteria.isRight()) { + TitanOperationStatus status = childrenByEdgeCriteria.right().value(); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List> list = childrenByEdgeCriteria.left().value(); + + Map artifactsMap = new HashMap<>(); + + for (ImmutablePair pair : list) { + ArtifactData artifactData = pair.getLeft(); + ArtifactDefinition artifactDefinition = new ArtifactDefinition(artifactData.getArtifactDataDefinition()); + + List heatParams = new ArrayList(); + StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId(), heatParams); + if (!heatParametersStatus.equals(StorageOperationStatus.OK)) { + log.debug("failed to get heat parameters for node {} {}", parentType.getName(), parentId); + return Either.right(heatParametersStatus); + } + if (!heatParams.isEmpty()) { + artifactDefinition.setHeatParameters(heatParams); + } + + Either, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactDefinition.getUniqueId(), GraphEdgeLabels.GENERATED_FROM, + NodeTypeEnum.ArtifactRef, ArtifactData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + if (!status.equals(TitanOperationStatus.NOT_FOUND)) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } else { + ImmutablePair immutablePair = getResult.left().value(); + artifactDefinition.setGeneratedFromId((String) immutablePair.left.getUniqueId()); + } + + artifactsMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + log.debug("Artifact {} was added to list ", artifactData.getUniqueId()); + } + + result = Either.left(artifactsMap); + return result; + + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + } + + @Override + public Either addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifactHeat, String parentId, NodeTypeEnum parentType, boolean inTransaction) { + + Either result = null; + try { + Either heatArtifactOnGraph = addArifactToComponent(artifactHeatEnv, parentId, parentType, true, true); + + if (heatArtifactOnGraph.isRight()) { + log.debug("failed to create heat env artifact on graph"); + result = heatArtifactOnGraph; + return result; + } + + ArtifactDefinition artifactDefinition = heatArtifactOnGraph.left().value(); + + // add relation from heatEnv to heat + UniqueIdData heatData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactHeat.getUniqueId()); + UniqueIdData heatEnvData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId()); + Either createRelation = titanGenericDao.createRelation(heatEnvData, heatData, GraphEdgeLabels.GENERATED_FROM, null); + + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + log.debug("failed to add relation from heat_env artifact to heat artifact. error: {}", status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + artifactDefinition.setGeneratedFromId(artifactHeat.getUniqueId()); + log.trace("heat env artifact added successfuly to resource instance"); + result = Either.left(artifactDefinition); + return result; + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + } + + public void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion) { + if (oldVesrion == null || oldVesrion.isEmpty()) + oldVesrion = "0"; + + String currentChecksum = artifactData.getArtifactChecksum(); + if (oldChecksum == null || oldChecksum.isEmpty()) { + if (currentChecksum != null) { + generateUUID(artifactData, oldVesrion); + } + } else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) { + generateUUID(artifactData, oldVesrion); + } + + } + + private void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) { + + UUID uuid = UUID.randomUUID(); + artifactData.setArtifactUUID(uuid.toString()); + MDC.put("serviceInstanceID", uuid.toString()); + long time = System.currentTimeMillis(); + artifactData.setPayloadUpdateDate(time); + int newVersion = new Integer(oldVesrion).intValue(); + newVersion++; + artifactData.setArtifactVersion(String.valueOf(newVersion)); + } + + @Override + public Either getHeatArtifactByHeatEnvId(String heatEnvId, boolean inTransaction) { + + Either result = null; + try { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Failed to work with graph {}", graph.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), heatEnvId).vertices(); + if (vertices == null || vertices.iterator() == null || false == vertices.iterator().hasNext()) { + log.debug("No nodes for type {} for id = {}", NodeTypeEnum.ArtifactRef, heatEnvId); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + Iterator iterator = vertices.iterator(); + Vertex vertex = iterator.next(); + + Map edgeProperties = null; + Either>, TitanOperationStatus> childrenByEdgeCriteria = titanGenericDao.getChildrenByEdgeCriteria(vertex, heatEnvId, GraphEdgeLabels.GENERATED_FROM, NodeTypeEnum.ArtifactRef, ArtifactData.class, + edgeProperties); + + if (childrenByEdgeCriteria.isRight()) { + TitanOperationStatus status = childrenByEdgeCriteria.right().value(); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List> list = childrenByEdgeCriteria.left().value(); + + if (list == null || list.isEmpty() == true) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + if (list.size() > 1) { + return Either.right(StorageOperationStatus.INVALID_ID); + } + + ImmutablePair immutablePair = list.get(0); + + ArtifactDefinition artifactDefinition = new ArtifactDefinition(immutablePair.left.getArtifactDataDefinition()); + + log.debug("The artifact {} was generated from artifact {}", heatEnvId, artifactDefinition); + + result = Either.left(artifactDefinition); + return result; + + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + } + + @Override + public Either getLatestArtifactDataByArtifactUUID(String artifactUUID, boolean inTransaction) { + Either result = null; + try { + NodeTypeEnum nodeType = NodeTypeEnum.ArtifactRef; + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.ARTIFACT_UUID.getProperty(), artifactUUID); + Either, TitanOperationStatus> getArtifactEither = titanGenericDao.getByCriteria(nodeType, propertiesToMatch, ArtifactData.class); + if (getArtifactEither.isRight()) { + log.debug("Couldn't fetch artifact data for artifact with uuid {}, error: {}", nodeType, getArtifactEither.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getArtifactEither.right().value())); + } else { + List artifacts = getArtifactEither.left().value(); + ArtifactData latestArtifact = artifacts.size() == 1 ? artifacts.get(0) + : artifacts.stream().max((a1, a2) -> Double.compare(Double.parseDouble(a1.getArtifactDataDefinition().getArtifactVersion()), Double.parseDouble(a2.getArtifactDataDefinition().getArtifactVersion()))).get(); + result = Either.left(latestArtifact); + } + return result; + } finally { + if (!inTransaction) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + } + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java new file mode 100644 index 0000000000..fc81a9affd --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java @@ -0,0 +1,463 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.operations.api.IAttributeOperation; +import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.AttributeValueData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +/** + * Class For Data Model Logic Relevant For Attributes + * + * @author mshitrit + * + */ +@Component("attribute-operation") +public class AttributeOperation extends AbstractOperation implements IAttributeOperation { + private static Logger log = LoggerFactory.getLogger(AttributeOperation.class.getName()); + @Autowired + private IPropertyOperation propertyOperation; + + /** + * + * Add attribute to graph. + * + * 1. Add attribute node + * + * 2. Add edge between the former node to its parent(if exists) + * + * 3. Add property node and associate it to the node created at #1. (per property & if exists) + * + * @param attributeDefinition + * @return + */ + private Either addAttributeToNodeType(AttributeDefinition attributeDefinition, NodeTypeEnum nodeType, String nodeUniqueId) { + String attUniqueId = UniqueIdBuilder.buildAttributeUid(nodeUniqueId, attributeDefinition.getName()); + Supplier dataBuilder = () -> buildAttributeData(attributeDefinition, attUniqueId); + Supplier defNameGenerator = () -> "Attribute : " + attributeDefinition.getName(); + + return addDefinitionToNodeType(attributeDefinition, nodeType, nodeUniqueId, GraphEdgeLabels.ATTRIBUTE, dataBuilder, defNameGenerator); + + } + + private TitanOperationStatus addAttributeToNodeType(TitanVertex metadataVertex, AttributeDefinition attributeDefinition, NodeTypeEnum nodeType, String nodeUniqueId) { + String attUniqueId = UniqueIdBuilder.buildAttributeUid(nodeUniqueId, attributeDefinition.getName()); + Supplier dataBuilder = () -> buildAttributeData(attributeDefinition, attUniqueId); + Supplier defNameGenerator = () -> "Attribute : " + attributeDefinition.getName(); + + return addDefinitionToNodeType(metadataVertex, attributeDefinition, nodeType, nodeUniqueId, GraphEdgeLabels.ATTRIBUTE, dataBuilder, defNameGenerator); + + } + + private AttributeData buildAttributeData(AttributeDefinition attributeDefinition, String attUniqueId) { + attributeDefinition.setUniqueId(attUniqueId); + return new AttributeData(attributeDefinition); + } + + @Override + public Either deleteAttribute(String attributeId) { + Either either = deleteAttributeFromGraph(attributeId); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + @Override + public Either, StorageOperationStatus> deleteAllAttributeAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) { + Wrapper errorWrapper; + List attributes = new ArrayList<>(); + TitanOperationStatus findAllResourceAttribues = findNodeNonInheretedAttribues(uniqueId, NodeTypeEnum.Resource, attributes); + errorWrapper = (findAllResourceAttribues != TitanOperationStatus.OK) ? new Wrapper<>(findAllResourceAttribues) : new Wrapper<>(); + + if (errorWrapper.isEmpty()) { + for (AttributeDefinition attDef : attributes) { + log.debug("Before deleting attribute from graph {}", attDef.getUniqueId()); + Either deleteNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Attribute), attDef.getUniqueId(), AttributeData.class); + if (deleteNode.isRight()) { + errorWrapper.setInnerElement(deleteNode.right().value()); + break; + } + } + } + + if (errorWrapper.isEmpty()) { + Map attributesMap = attributes.stream().collect(Collectors.toMap(e -> e.getName(), e -> e)); + return Either.left(attributesMap); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(errorWrapper.getInnerElement())); + } + + } + + private Either deleteAttributeFromGraph(String attributeId) { + log.debug("Before deleting attribute from graph {}", attributeId); + return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Attribute), attributeId, AttributeData.class); + } + + @Override + public TitanOperationStatus addAttributesToGraph(TitanVertex metadataVertex, Map attributes, String resourceId, Map dataTypes) { + TitanOperationStatus titanStatus = TitanOperationStatus.OK; + for (AttributeDefinition attribute : attributes.values()) { + TitanOperationStatus eitherAddAttribute = addAttributeToGraphByVertex(metadataVertex, attribute, resourceId, dataTypes); + if (!eitherAddAttribute.equals(TitanOperationStatus.OK)) { + titanStatus = eitherAddAttribute; + break; + } + } + return titanStatus; + } + + @Override + public Either, TitanOperationStatus> getAllAttributesOfResourceInstance(ComponentInstance compInstance) { + + Either, TitanOperationStatus> result; + + Either>, TitanOperationStatus> attributeImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), compInstance.getUniqueId(), + GraphEdgeLabels.ATTRIBUTE_VALUE, NodeTypeEnum.AttributeValue, AttributeValueData.class); + + // Build From Resource + if (attributeImplNodes.isRight() && attributeImplNodes.right().value() == TitanOperationStatus.NOT_FOUND) { + result = getAttributesFromResource(compInstance); + } + // Build From Instance + else if (attributeImplNodes.isLeft()) { + List> attributesFromRI = attributeImplNodes.left().value(); + result = mergeAttributesResults(getAttributesFromResource(compInstance), convertToComponentInstanceAttribute(attributesFromRI)); + } + // Error + else { + TitanOperationStatus status = attributeImplNodes.right().value(); + result = Either.right(status); + } + + return result; + } + + private Either, TitanOperationStatus> mergeAttributesResults(Either, TitanOperationStatus> eitherAttributesThatDoesNotExistOnRI, + Either, TitanOperationStatus> eitherAttributesThatExistOnRI) { + + Either, TitanOperationStatus> result; + if (eitherAttributesThatExistOnRI.isRight()) { + result = Either.right(eitherAttributesThatExistOnRI.right().value()); + } else if (eitherAttributesThatDoesNotExistOnRI.isRight()) { + result = Either.right(eitherAttributesThatDoesNotExistOnRI.right().value()); + } else { + final List attributesThatExistOnRI = eitherAttributesThatExistOnRI.left().value(); + final List attributesThatDoesNotExistOnRI = eitherAttributesThatDoesNotExistOnRI.left().value(); + Set attributesIdThatExistOnRI = attributesThatExistOnRI.stream().map(e -> e.getUniqueId()).collect(Collectors.toSet()); + // Attributes From The Resource Without attributes that also exist + // on the instance + Stream filterAttributesThatDoesNotExistOnRI = attributesThatDoesNotExistOnRI.stream().filter(e -> !attributesIdThatExistOnRI.contains(e.getUniqueId())); + // Add Fields From Resource Attributes + fillAttributeInfoFromResource(attributesThatExistOnRI, attributesThatDoesNotExistOnRI); + // Adding the Attributes on the instance for the full list + List mergedList = Stream.concat(filterAttributesThatDoesNotExistOnRI, attributesThatExistOnRI.stream()).collect(Collectors.toList()); + result = Either.left(mergedList); + } + return result; + } + + private void fillAttributeInfoFromResource(List attributesThatExistOnRI, List attributesThatDoesNotExistOnRI) { + attributesThatExistOnRI.stream() + .forEach(e -> addAttributeInfo(e, + // Finds the same attribute in the resource + attributesThatDoesNotExistOnRI.stream().filter(e2 -> e2.getUniqueId().equals(e.getUniqueId())).findAny().get())); + + } + + private void addAttributeInfo(ComponentInstanceAttribute attributeFromRI, ComponentInstanceAttribute attributeFromResource) { + attributeFromRI.setName(attributeFromResource.getName()); + attributeFromRI.setDescription(attributeFromResource.getDescription()); + attributeFromRI.setDefaultValue(attributeFromResource.getDefaultValue()); + attributeFromRI.setStatus(attributeFromResource.getStatus()); + attributeFromRI.setSchema(attributeFromResource.getSchema()); + if (StringUtils.isEmpty(attributeFromRI.getValue())) { + attributeFromRI.setValue(attributeFromResource.getDefaultValue()); + } + } + + private Either, TitanOperationStatus> getAttributesFromResource(ComponentInstance compInstance) { + Either, TitanOperationStatus> result; + List attributes = new ArrayList<>(); + // Attributes does not exist on Ri - fetch them from resource + TitanOperationStatus findAllResourceAttribues = findAllResourceAttributesRecursively(compInstance.getComponentUid(), attributes); + if (findAllResourceAttribues != TitanOperationStatus.OK) { + result = Either.right(findAllResourceAttribues); + } else { + List buildAttInstanceFromResource = attributes.stream().map(attDef -> new ComponentInstanceAttribute(attDef, false, null)).collect(Collectors.toList()); + + // Set Value to be default value in case it is empty + Consumer valueSetter = data -> { + if (StringUtils.isEmpty(data.getValue())) { + data.setValue(data.getDefaultValue()); + } + }; + buildAttInstanceFromResource.stream().forEach(valueSetter); + + result = Either.left(buildAttInstanceFromResource); + } + return result; + } + + private Either, TitanOperationStatus> convertToComponentInstanceAttribute(List> list) { + Either, TitanOperationStatus> result = null; + List componentInstanceAttribute = new ArrayList<>(); + for (ImmutablePair attributeValue : list) { + AttributeValueData attributeValueData = attributeValue.getLeft(); + String attributeValueUid = attributeValueData.getUniqueId(); + + Either, TitanOperationStatus> attributeDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.AttributeValue), attributeValueUid, GraphEdgeLabels.ATTRIBUTE_IMPL, + NodeTypeEnum.Attribute, AttributeData.class); + + if (attributeDefRes.isRight()) { + TitanOperationStatus status = attributeDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + result = Either.right(status); + break; + } else { + ImmutablePair attributeDefPair = attributeDefRes.left().value(); + String attributeUniqueId = attributeDefPair.left.getUniqueId(); + + ComponentInstanceAttribute resourceInstanceAttribute = new ComponentInstanceAttribute(); + // set attribute original unique id + resourceInstanceAttribute.setUniqueId(attributeUniqueId); + // set hidden + resourceInstanceAttribute.setHidden(attributeValueData.isHidden()); + // set value + resourceInstanceAttribute.setValue(attributeValueData.getValue()); + // set property value unique id + resourceInstanceAttribute.setValueUniqueUid(attributeValueUid); + + resourceInstanceAttribute.setType(attributeValueData.getType()); + + componentInstanceAttribute.add(resourceInstanceAttribute); + } + + } + if (result == null) { + result = Either.left(componentInstanceAttribute); + } + return result; + } + + /** + * fetch all attributes under a given resource(includes its parents' resources) + * + * @param resourceId + * @param attributes + * @return + */ + @Override + public TitanOperationStatus findAllResourceAttributesRecursively(String resourceId, List attributes) { + final NodeElementFetcher singleNodeFetcher = (resourceIdParam, attributesParam) -> findNodeNonInheretedAttribues(resourceIdParam, NodeTypeEnum.Resource, attributesParam); + return findAllResourceElementsDefinitionRecursively(resourceId, attributes, singleNodeFetcher); + + } + + @Override + public TitanOperationStatus findNodeNonInheretedAttribues(String uniqueId, NodeTypeEnum nodeType, List attributes) { + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.ATTRIBUTE, NodeTypeEnum.Attribute, + AttributeData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return status; + } + + List> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair immutablePair : values) { + AttributeData attData = immutablePair.getLeft(); + String attributeName = attData.getAttributeDataDefinition().getName(); + + log.debug("Attribute {} is associated to node {}", attributeName, uniqueId); + AttributeData attributeData = immutablePair.getKey(); + AttributeDefinition attributeDefinition = this.convertAttributeDataToAttributeDefinition(attributeData, attributeName, uniqueId); + + attributes.add(attributeDefinition); + + log.trace("findAttributesOfNode - property {} associated to node {}", attributeDefinition, uniqueId); + } + + } + + return TitanOperationStatus.OK; + } + + @Override + public AttributeDefinition convertAttributeDataToAttributeDefinition(AttributeData attributeData, String attributeName, String resourceId) { + log.debug("The object returned after create attribute is {}", attributeData); + AttributeDefinition attributeDefResult = new AttributeDefinition(attributeData.getAttributeDataDefinition()); + attributeDefResult.setName(attributeName); + attributeDefResult.setParentUniqueId(resourceId); + return attributeDefResult; + } + + @Override + public Either addAttribute(AttributeDefinition attributeDefinition, String resourceId) { + + Either eitherResult; + Either, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + eitherResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + Either either = addAttributeToGraph(attributeDefinition, resourceId, allDataTypes.left().value()); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + eitherResult = Either.right(storageStatus); + } else { + eitherResult = Either.left(either.left().value()); + } + } + return eitherResult; + } + + @Override + public Either updateAttribute(String attributeId, AttributeDefinition newAttDef, Map dataTypes) { + + StorageOperationStatus validateAndUpdateAttribute = propertyOperation.validateAndUpdateProperty(newAttDef, dataTypes); + if (validateAndUpdateAttribute != StorageOperationStatus.OK) { + return Either.right(validateAndUpdateAttribute); + } + + Either either = updateAttributeFromGraph(attributeId, newAttDef); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + private Either updateAttributeFromGraph(String attributeId, AttributeDefinition attributeDefenition) { + log.debug("Before updating attribute on graph {}", attributeId); + + // get the original property data + Either eitherAttribute = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Attribute), attributeId, AttributeData.class); + if (eitherAttribute.isRight()) { + log.debug("Problem while get Attribute with id {}. Reason - {}", attributeId, eitherAttribute.right().value().name()); + return Either.right(eitherAttribute.right().value()); + } + AttributeData orgAttributeData = eitherAttribute.left().value(); + AttributeDataDefinition orgAttributeDataDefinition = orgAttributeData.getAttributeDataDefinition(); + + // create new property data to update + AttributeData newAttributeData = new AttributeData(); + newAttributeData.setAttributeDataDefinition(attributeDefenition); + AttributeDataDefinition newAttributeDataDefinition = newAttributeData.getAttributeDataDefinition(); + + // update the original property data with new values + if (!Objects.equals(orgAttributeDataDefinition.getDefaultValue(), newAttributeDataDefinition.getDefaultValue())) { + orgAttributeDataDefinition.setDefaultValue(newAttributeDataDefinition.getDefaultValue()); + } + + if (!Objects.equals(orgAttributeDataDefinition.getDescription(), newAttributeDataDefinition.getDescription())) { + orgAttributeDataDefinition.setDescription(newAttributeDataDefinition.getDescription()); + } + + if (!Objects.equals(orgAttributeDataDefinition.getType(), newAttributeDataDefinition.getType())) { + orgAttributeDataDefinition.setType(newAttributeDataDefinition.getType()); + } + + orgAttributeDataDefinition.setSchema(newAttributeDataDefinition.getSchema()); + + return titanGenericDao.updateNode(orgAttributeData, AttributeData.class); + } + + @Override + public ComponentInstanceAttribute buildResourceInstanceAttribute(AttributeValueData attributeValueData, ComponentInstanceAttribute resourceInstanceAttribute) { + + Boolean hidden = attributeValueData.isHidden(); + String uid = attributeValueData.getUniqueId(); + ComponentInstanceAttribute instanceAttribute = new ComponentInstanceAttribute(resourceInstanceAttribute, hidden, uid); + + return instanceAttribute; + } + + @Override + public Either addAttributeToGraph(AttributeDefinition attribute, String resourceId, Map dataTypes) { + Either eitherResult; + StorageOperationStatus validateAndUpdateAttribute = propertyOperation.validateAndUpdateProperty(attribute, dataTypes); + if (validateAndUpdateAttribute != StorageOperationStatus.OK) { + log.error("Attribute " + attribute + " is invalid. Status is " + validateAndUpdateAttribute); + eitherResult = Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } else { + eitherResult = addAttributeToNodeType(attribute, NodeTypeEnum.Resource, resourceId); + + } + return eitherResult; + } + + @Override + public TitanOperationStatus addAttributeToGraphByVertex(TitanVertex metadataVertex, AttributeDefinition attribute, String resourceId, Map dataTypes) { + StorageOperationStatus validateAndUpdateAttribute = propertyOperation.validateAndUpdateProperty(attribute, dataTypes); + TitanOperationStatus result; + if (validateAndUpdateAttribute != StorageOperationStatus.OK) { + log.error("Attribute {} is invalid. Status is {}", attribute, validateAndUpdateAttribute); + result = TitanOperationStatus.ILLEGAL_ARGUMENT; + } else { + result = addAttributeToNodeType(metadataVertex, attribute, NodeTypeEnum.Resource, resourceId); + + } + return result; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java new file mode 100644 index 0000000000..d05255473d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.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.be.model.operations.impl; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.cache.*; +import org.openecomp.sdc.be.model.cache.jobs.*; +import org.openecomp.sdc.be.model.cache.workers.CacheWorker; +import org.openecomp.sdc.be.model.cache.workers.IWorker; +import org.openecomp.sdc.be.model.cache.workers.SyncWorker; +import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; +import org.openecomp.sdc.be.model.operations.api.IProductOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; +import org.openecomp.sdc.be.workers.Manager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.util.LinkedList; +import java.util.concurrent.*; + +/** + * Created by mlando on 9/5/2016. the class is responsible for handling all + * cache update operations asynchronously including sync between the graph and + * cache and on demand update requests + */ +@Component("cacheManger-operation") +public class CacheMangerOperation implements ICacheMangerOperation { + @Autowired + private IResourceOperation iResourceOperation; + @Autowired + private IServiceOperation iServiceOperation; + @Autowired + private IProductOperation iProductOperation; + @Autowired + private TitanGenericDao titanGenericDao; + @Autowired + private ComponentCache componentCache; + + private static Logger log = LoggerFactory.getLogger(Manager.class.getName()); + private LinkedBlockingQueue jobQueue = null; + private int waitOnShutDownInMinutes; + private ScheduledExecutorService syncExecutor; + private ExecutorService workerExecutor; + private LinkedList workerList = new LinkedList<>(); + private DaoInfo daoInfo; + + /** + * constructor + */ + public CacheMangerOperation() { + // daoInfo = new DaoInfo(iResourceOperation, iServiceOperation, + // iProductOperation, componentCache); + } + + /** + * the method checks in the cache is enabled, if it is, it initializes all + * the workers according to the configuration values. + */ + @PostConstruct + public void init() { + + daoInfo = new DaoInfo(iResourceOperation, iServiceOperation, iProductOperation, componentCache); + + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + Integer numberOfWorkers = applicationL2CacheConfig.getQueue().getNumberOfCacheWorkers(); + this.waitOnShutDownInMinutes = applicationL2CacheConfig.getQueue().getWaitOnShutDownInMinutes(); + jobQueue = new LinkedBlockingQueue<>(); + log.info("L2 Cache is enabled inishilsing queue"); + log.debug("initializing SyncWorker, creating {} workers"); + ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Sync-Cache-Worker-%d").build(); + this.syncExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory); + log.debug("initializing workers, creating {} cacheWorkers", numberOfWorkers); + threadFactory = new ThreadFactoryBuilder().setNameFormat("Cache-Worker-%d").build(); + String workerName = "Sync-Worker"; + Integer syncWorkerExacutionIntrval = applicationL2CacheConfig.getQueue().getSyncIntervalInSecondes(); + log.debug("starting Sync worker:{} with executions interval:{} ", workerName, syncWorkerExacutionIntrval); + SyncWorker syncWorker = new SyncWorker(workerName, this); + this.syncExecutor.scheduleAtFixedRate(syncWorker, 5 * 60, syncWorkerExacutionIntrval, TimeUnit.SECONDS); + this.workerExecutor = Executors.newFixedThreadPool(numberOfWorkers, threadFactory); + CacheWorker cacheWorker; + for (int i = 0; i < numberOfWorkers; i++) { + workerName = "Cache-Worker-" + i; + log.debug("starting Cache worker:{}", workerName); + cacheWorker = new CacheWorker(workerName, jobQueue); + this.workerExecutor.submit(cacheWorker); + this.workerList.add(cacheWorker); + } + } else { + log.info("L2 Cache is disabled"); + } + log.info("L2 Cache has been initialized and the workers are running"); + } + + /** + * the method creates a job to check it the given component is in the cach + * and if so is it valid if the value in the cache is not valid it will be + * updated. + * + * @param componentId + * the uid of the component we want to update + * @param timestamp + * the time of the component update + * @param nodeTypeEnum + * the type of the component resource/service/product + */ + @Override + public void updateComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) { + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + this.jobQueue.add(new CheckAndUpdateJob(daoInfo, componentId, nodeTypeEnum, timestamp)); + } + } + + public void overideComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) { + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + this.jobQueue.add(new OverrideJob(daoInfo, componentId, nodeTypeEnum, timestamp)); + } + } + + public void deleteComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) { + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + this.jobQueue.add(new DeleteJob(daoInfo, componentId, nodeTypeEnum, timestamp)); + } + } + + /** + * the method stores the given component in the cache + * + * @param component + * componet to store in cache + * @param nodeTypeEnum + * the type of the component we want to store + */ + @Override + public void storeComponentInCache(org.openecomp.sdc.be.model.Component component, NodeTypeEnum nodeTypeEnum) { + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + this.jobQueue.add(new StoreJob(daoInfo, component, nodeTypeEnum)); + } + } + + /** + * the method shutdown's all the worker's. the method has a pre set of how + * long it will wait for the workers to shutdown. the pre defined value is + * taken from the configuration. + */ + @PreDestroy + public void shutDown() { + workerExecutor.shutdown(); + syncExecutor.shutdown(); + this.workerList.forEach(e -> e.shutDown()); + try { + if (!workerExecutor.awaitTermination(this.waitOnShutDownInMinutes, TimeUnit.MINUTES)) { + log.error("timer elapsed while waiting for Cache workers to finish, forcing a shutdown. "); + } + log.debug("all Cache workers finished"); + } catch (InterruptedException e) { + log.error("failed while waiting for Cache worker", e); + } + try { + if (!workerExecutor.awaitTermination(1, TimeUnit.MINUTES)) { + log.error("timer elapsed while waiting for the Sync worker's to finish, forcing a shutdown. "); + } + log.debug("sync worker finished"); + } catch (InterruptedException e) { + log.error("failed while waiting for sync worker", e); + } + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public ComponentCache getComponentCache() { + return componentCache; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityInstanceOperation.java new file mode 100644 index 0000000000..0c4f35fd54 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityInstanceOperation.java @@ -0,0 +1,1215 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +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.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +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.operations.api.ICapabilityInstanceOperation; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +/** + * public class CapabilityInstanceOperation provides methods for CRUD operations for CapabilityInstance on component instance level + * + * @author ns019t + * + */ +@Component("capability-instance-operation") +public class CapabilityInstanceOperation extends AbstractOperation implements ICapabilityInstanceOperation { + + private static Logger log = LoggerFactory.getLogger(CapabilityOperation.class.getName()); + + @Autowired + private PropertyOperation propertyOperation; + + @Autowired + private CapabilityOperation capabilityOperation; + + /** + * String constants for logger + */ + private String statusIs = ". status is "; + private String dot = "."; + private String onGraph = " on graph "; + private String ofRI = " of resource instance "; + private String toCapability = " to capability "; + private String toCI = " to capability instance "; + private String toProperty = " to property "; + private String forRI = " for resource instance "; + private String failedCreateCI = "Failed to create capability instance of capability "; + private String failedAddProperties = "Failed to add properties to capability instance "; + private String ofCI = " of component instance "; + private String failedDeletePropertyValues = "Failed to delete property values of capability instance "; + private String toValue = " to property value "; + private String fromRI = " from resource instance "; + + /** + * create capability instance of capability with property values for resource instance + * + * @param resourceInstanceId + * @param capabilityId + * @param propertyValues + * @param validateCapabilityInstExistence + * @param capabilityName + * @return + */ + @Override + public Either>, TitanOperationStatus> createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance(String resourceInstanceId, String capabilityId, String capabilityName, + List propertyValues, boolean validateCapabilityInstExistence) { + Wrapper errorWrapper = new Wrapper<>(); + Wrapper overrideCapabilityDataWrapper = new Wrapper<>(); + Wrapper overrideCapabilityDefinitionWrapper = new Wrapper<>(); + Either createCapabilityRes = null; + CapabilityInstData createdCapabilityInstance = null; + + Wrapper> defaultPropertiesWrapper = new Wrapper<>(); + Either, TitanOperationStatus> getCapabilityRes = null; + Either getCapabilityDefinitionRes = null; + Either, TitanOperationStatus> addPropertyValuesRes = null; + Wrapper createdCapabilityInstanceIdWrapper = new Wrapper<>(); + if (validateCapabilityInstExistence) { + validateCapabilityInstanceExistence(resourceInstanceId, capabilityId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + getCapabilityRes = getCapabilitiesOfResourceInstance(resourceInstanceId, capabilityId, capabilityName, errorWrapper); + } + if (errorWrapper.isEmpty()) { + getCapabilityDefinitionRes = getCapabiityDefinition(resourceInstanceId, capabilityId, errorWrapper, overrideCapabilityDataWrapper, getCapabilityRes); + } + if (errorWrapper.isEmpty()) { + createCapabilityRes = createCapabilityInstanceOnGraph(resourceInstanceId, capabilityId, errorWrapper, overrideCapabilityDataWrapper, overrideCapabilityDefinitionWrapper, getCapabilityDefinitionRes); + } + if (errorWrapper.isEmpty() && overrideCapabilityDefinitionWrapper.getInnerElement().getProperties() != null) { + createdCapabilityInstance = validateCapabilityInstanceProperties(resourceInstanceId, propertyValues, errorWrapper, overrideCapabilityDefinitionWrapper, createCapabilityRes, defaultPropertiesWrapper, createdCapabilityInstanceIdWrapper); + } + if (errorWrapper.isEmpty()) { + addPropertyValuesRes = addPropertyValueToCapabilityInstance(resourceInstanceId, propertyValues, errorWrapper, createCapabilityRes, defaultPropertiesWrapper, createdCapabilityInstanceIdWrapper); + } + Either>, TitanOperationStatus> result; + if (errorWrapper.isEmpty()) { + Map> resultMap = new HashMap<>(); + resultMap.put(createdCapabilityInstance, addPropertyValuesRes.left().value()); + result = Either.left(resultMap); + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + @Override + public TitanOperationStatus createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance(TitanVertex resourceInstanceVertex, String resourceInstanceId, String capabilityId, String capabilityName, + List propertyValues, boolean validateCapabilityInstExistence) { + Wrapper errorWrapper = new Wrapper<>(); + Wrapper overrideCapabilityDataWrapper = new Wrapper<>(); + Wrapper overrideCapabilityDefinitionWrapper = new Wrapper<>(); + Either createCapabilityRes = null; + TitanVertex createdCapabilityInstance = null; + + Wrapper> defaultPropertiesWrapper = new Wrapper<>(); + Either, TitanOperationStatus> getCapabilityRes = null; + Either getCapabilityDefinitionRes = null; + TitanOperationStatus addPropertyValuesRes = null; + Wrapper createdCapabilityInstanceIdWrapper = new Wrapper<>(); + if (validateCapabilityInstExistence) { + validateCapabilityInstanceExistence(resourceInstanceVertex, resourceInstanceId, capabilityId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + getCapabilityRes = getCapabilitiesOfResourceInstance(resourceInstanceVertex, resourceInstanceId, capabilityId, capabilityName, errorWrapper); + } + if (errorWrapper.isEmpty()) { + getCapabilityDefinitionRes = getCapabiityDefinitionByVertex(resourceInstanceId, capabilityId, errorWrapper, overrideCapabilityDataWrapper, getCapabilityRes); + } + if (errorWrapper.isEmpty()) { + createCapabilityRes = createCapabilityInstanceOnGraphByVertex(resourceInstanceVertex, resourceInstanceId, capabilityId, errorWrapper, overrideCapabilityDataWrapper, overrideCapabilityDefinitionWrapper, getCapabilityDefinitionRes); + } + if (errorWrapper.isEmpty() && overrideCapabilityDefinitionWrapper.getInnerElement().getProperties() != null) { + createdCapabilityInstance = validateCapabilityInstancePropertiesByVertex(resourceInstanceId, propertyValues, errorWrapper, overrideCapabilityDefinitionWrapper, createCapabilityRes.left().value(), defaultPropertiesWrapper, + createdCapabilityInstanceIdWrapper); + } + if (errorWrapper.isEmpty()) { + addPropertyValuesRes = addPropertyValueToCapabilityInstanceByVertex(resourceInstanceId, propertyValues, errorWrapper, createCapabilityRes, defaultPropertiesWrapper, createdCapabilityInstanceIdWrapper); + } + + return addPropertyValuesRes; + } + + private Either, TitanOperationStatus> addPropertyValueToCapabilityInstance(String resourceInstanceId, List propertyValues, Wrapper errorWrapper, + Either createCapabilityRes, Wrapper> defaultPropertiesWrapper, Wrapper createdCapabilityInstanceIdWrapper) { + Either, TitanOperationStatus> addPropertyValuesRes; + log.debug("Before adding property values to capability instance {} dot", createdCapabilityInstanceIdWrapper.getInnerElement()); + addPropertyValuesRes = addPropertyValuesToCapabilityInstance(createCapabilityRes.left().value(), propertyValues, defaultPropertiesWrapper.getInnerElement()); + if (addPropertyValuesRes.isRight()) { + errorWrapper.setInnerElement(addPropertyValuesRes.right().value()); + log.debug("failedAddProperties {} ofRI {} statusIs {} dot", createdCapabilityInstanceIdWrapper.getInnerElement(), resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After adding property values to capability instance {} status is {}.", createdCapabilityInstanceIdWrapper.getInnerElement(), errorWrapper.getInnerElement()); + return addPropertyValuesRes; + } + + private TitanOperationStatus addPropertyValueToCapabilityInstanceByVertex(String resourceInstanceId, List propertyValues, Wrapper errorWrapper, + Either createCapabilityRes, Wrapper> defaultPropertiesWrapper, Wrapper createdCapabilityInstanceIdWrapper) { + log.trace("Before adding property values to capability instance {}", createdCapabilityInstanceIdWrapper.getInnerElement()); + TitanOperationStatus addPropertyValuesRes = addPropertyValuesToCapabilityInstance(createCapabilityRes.left().value(), propertyValues, defaultPropertiesWrapper.getInnerElement()); + if (!addPropertyValuesRes.equals(TitanOperationStatus.OK)) { + errorWrapper.setInnerElement(addPropertyValuesRes); + log.debug("Failed to add properties to capability instance {} {} {} {} {}", createdCapabilityInstanceIdWrapper.getInnerElement(), ofRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + } + log.trace("After adding property values to capability instance {} {} {}", createdCapabilityInstanceIdWrapper.getInnerElement(), statusIs, errorWrapper.getInnerElement()); + return addPropertyValuesRes; + } + + private CapabilityInstData validateCapabilityInstanceProperties(String resourceInstanceId, List propertyValues, Wrapper errorWrapper, + Wrapper overrideCapabilityDefinitionWrapper, Either createCapabilityRes, Wrapper> defaultPropertiesWrapper, + Wrapper createdCapabilityInstanceIdWrapper) { + CapabilityInstData createdCapabilityInstance; + createdCapabilityInstance = createCapabilityRes.left().value(); + createdCapabilityInstanceIdWrapper.setInnerElement(createdCapabilityInstance.getUniqueId()); + Map defaultProperties = overrideCapabilityDefinitionWrapper.getInnerElement().getProperties().stream().collect(Collectors.toMap(PropertyDefinition::getName, Function.identity())); + defaultPropertiesWrapper.setInnerElement(defaultProperties); + log.debug("Before validating property values of capability instance {}.", createdCapabilityInstanceIdWrapper.getInnerElement()); + Either result = validateCapabilityInstanceProperties(defaultProperties, propertyValues); + if (result.isRight()) { + errorWrapper.setInnerElement(result.right().value()); + log.debug("failedAddProperties {} ofRI {} statusIs {}.", createdCapabilityInstanceIdWrapper.getInnerElement(), resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After validating property values of capability instance {} status is {}.", createdCapabilityInstanceIdWrapper.getInnerElement(), errorWrapper.getInnerElement()); + return createdCapabilityInstance; + } + + private TitanVertex validateCapabilityInstancePropertiesByVertex(String resourceInstanceId, List propertyValues, Wrapper errorWrapper, + Wrapper overrideCapabilityDefinitionWrapper, TitanVertex createCapabilityRes, Wrapper> defaultPropertiesWrapper, Wrapper createdCapabilityInstanceIdWrapper) { + String id = (String) titanGenericDao.getProperty(createCapabilityRes, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + createdCapabilityInstanceIdWrapper.setInnerElement(id); + Map defaultProperties = overrideCapabilityDefinitionWrapper.getInnerElement().getProperties().stream().collect(Collectors.toMap(PropertyDefinition::getName, Function.identity())); + defaultPropertiesWrapper.setInnerElement(defaultProperties); + log.trace("Before validating property values of capability instance {}", createdCapabilityInstanceIdWrapper.getInnerElement()); + Either result = validateCapabilityInstanceProperties(defaultProperties, propertyValues); + if (result.isRight()) { + errorWrapper.setInnerElement(result.right().value()); + log.debug("Failed to add properties to capability instance {} {} {} {} {}", createdCapabilityInstanceIdWrapper.getInnerElement(), ofRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + } + log.trace("After validating property values of capability instance {} {} {}", createdCapabilityInstanceIdWrapper.getInnerElement(), statusIs, errorWrapper.getInnerElement()); + return createCapabilityRes; + } + + private Either createCapabilityInstanceOnGraph(String resourceInstanceId, String capabilityId, Wrapper errorWrapper, Wrapper overrideCapabilityDataWrapper, + Wrapper overrideCapabilityDefinitionWrapper, Either getCapabilityDefinitionRes) { + Either createCapabilityRes; + log.debug("Before creating capability instance of capability {} on graph.", capabilityId); + overrideCapabilityDefinitionWrapper.setInnerElement(getCapabilityDefinitionRes.left().value()); + CapabilityInstData capabilityInstance = buildCapabilityInstanceData(resourceInstanceId, overrideCapabilityDefinitionWrapper.getInnerElement()); + createCapabilityRes = createCapabilityInstanceOnGraph(resourceInstanceId, overrideCapabilityDataWrapper.getInnerElement(), capabilityInstance); + if (createCapabilityRes.isRight()) { + errorWrapper.setInnerElement(createCapabilityRes.right().value()); + log.debug("failedCreateCI {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After creating capability instance of capability {} on graph. Status is {}", capabilityId, errorWrapper.getInnerElement()); + return createCapabilityRes; + } + + private Either createCapabilityInstanceOnGraphByVertex(TitanVertex riVertex, String resourceInstanceId, String capabilityId, Wrapper errorWrapper, + Wrapper overrideCapabilityDataWrapper, Wrapper overrideCapabilityDefinitionWrapper, Either getCapabilityDefinitionRes) { + Either createCapabilityRes; + log.trace("Before creating capability instance of capability {} {}", capabilityId, onGraph); + overrideCapabilityDefinitionWrapper.setInnerElement(getCapabilityDefinitionRes.left().value()); + CapabilityInstData capabilityInstance = buildCapabilityInstanceData(resourceInstanceId, overrideCapabilityDefinitionWrapper.getInnerElement()); + createCapabilityRes = createCapabilityInstanceOnGraph(riVertex, resourceInstanceId, overrideCapabilityDataWrapper.getInnerElement(), capabilityInstance); + if (createCapabilityRes.isRight()) { + errorWrapper.setInnerElement(createCapabilityRes.right().value()); + log.debug("Failed to create capability instance of capability {} {} {} {} {} ", capabilityId, ofRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + } + log.debug("After creating capability instance of capability {} {} {} {} {}", capabilityId, onGraph, statusIs, errorWrapper.getInnerElement()); + return createCapabilityRes; + } + + private Either getCapabiityDefinition(String resourceInstanceId, String capabilityId, Wrapper errorWrapper, Wrapper overrideCapabilityDataWrapper, + Either, TitanOperationStatus> getCapabilityRes) { + Either getCapabilityDefinitionRes; + log.debug("Before getting capability definition {} forRI {}.", capabilityId, resourceInstanceId); + CapabilityData overrideCapabilityData = getCapabilityRes.left().value().getLeft(); + overrideCapabilityDataWrapper.setInnerElement(overrideCapabilityData); + getCapabilityDefinitionRes = capabilityOperation.getCapabilityByCapabilityData(overrideCapabilityData); + if (getCapabilityDefinitionRes.isRight()) { + errorWrapper.setInnerElement(getCapabilityDefinitionRes.right().value()); + log.debug("Failed to retrieve capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After getting capability definition for {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + return getCapabilityDefinitionRes; + } + + private Either getCapabiityDefinitionByVertex(String resourceInstanceId, String capabilityId, Wrapper errorWrapper, Wrapper overrideCapabilityDataWrapper, + Either, TitanOperationStatus> getCapabilityRes) { + Either getCapabilityDefinitionRes; + log.trace("Before getting capability definition {} {} {}", capabilityId, forRI, resourceInstanceId); + + TitanVertex overrideCapabilityData = getCapabilityRes.left().value().getLeft(); + + overrideCapabilityDataWrapper.setInnerElement(overrideCapabilityData); + getCapabilityDefinitionRes = capabilityOperation.getCapabilityByCapabilityData(overrideCapabilityData); + if (getCapabilityDefinitionRes.isRight()) { + errorWrapper.setInnerElement(getCapabilityDefinitionRes.right().value()); + log.debug("Failed to retrieve capability {} ofRI {} statusIs {}", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After getting capability definition for {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + return getCapabilityDefinitionRes; + } + + private Either, TitanOperationStatus> getCapabilitiesOfResourceInstance(String resourceInstanceId, String capabilityId, String capabilityName, Wrapper errorWrapper) { + Either, TitanOperationStatus> getCapabilityRes; + log.debug("Before getting capability {} forRI {}.", capabilityId, resourceInstanceId); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + getCapabilityRes = titanGenericDao.getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class, props); + if (getCapabilityRes.isRight()) { + errorWrapper.setInnerElement(getCapabilityRes.right().value()); + log.debug("Failed to get capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After getting capability for {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + return getCapabilityRes; + } + + private Either, TitanOperationStatus> getCapabilitiesOfResourceInstance(TitanVertex instanceVertex, String resourceInstanceId, String capabilityId, String capabilityName, + Wrapper errorWrapper) { + Either, TitanOperationStatus> getCapabilityRes; + log.trace("Before getting capability {} {} {}", capabilityId, forRI, resourceInstanceId); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + getCapabilityRes = titanGenericDao.getChildByEdgeCriteria(instanceVertex, GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (getCapabilityRes.isRight()) { + errorWrapper.setInnerElement(getCapabilityRes.right().value()); + log.debug("Failed to get capability {} {} {} {} {}", capabilityId, ofRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + } + log.trace("After getting capability for {} {} {} {} {}", capabilityId, forRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + return getCapabilityRes; + } + + private void validateCapabilityInstanceExistence(String resourceInstanceId, String capabilityId, Wrapper errorWrapper) { + log.debug("Before validation of existence of capability instance of capability {} forRI {}.", capabilityId, resourceInstanceId); + boolean capabilityInstOfCapabilityAlreadyExists; + Either validateCapabilityInstExistenceRes = validateCapabilityInstExistence(resourceInstanceId, capabilityId); + if (validateCapabilityInstExistenceRes.isRight()) { + errorWrapper.setInnerElement(validateCapabilityInstExistenceRes.right().value()); + log.debug("Failed to validate uniqueness of capability instance of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } else { + capabilityInstOfCapabilityAlreadyExists = validateCapabilityInstExistenceRes.left().value(); + if (capabilityInstOfCapabilityAlreadyExists) { + errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST); + log.debug("failedCreateCI {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + } + log.debug("After validation of existence of capability instance of capability {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + + private void validateCapabilityInstanceExistence(TitanVertex resourceInstanceVertex, String resourceInstanceId, String capabilityId, Wrapper errorWrapper) { + log.trace("Before validation of existence of capability instance of capability {} {} {}", capabilityId, forRI, resourceInstanceId); + boolean capabilityInstOfCapabilityAlreadyExists; + Either validateCapabilityInstExistenceRes = validateCapabilityInstExistence(resourceInstanceId, capabilityId); + if (validateCapabilityInstExistenceRes.isRight()) { + errorWrapper.setInnerElement(validateCapabilityInstExistenceRes.right().value()); + log.debug("Failed to validate uniqueness of capability instance of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } else { + capabilityInstOfCapabilityAlreadyExists = validateCapabilityInstExistenceRes.left().value(); + if (capabilityInstOfCapabilityAlreadyExists) { + errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST); + log.debug("failedCreateCI {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + } + log.debug("After validation of existence of capability instance of capability {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + + private Either, TitanOperationStatus> addPropertyValuesToCapabilityInstance(CapabilityInstData createdCapabilityInstance, List propertyValues, Map defaultProperties) { + TitanOperationStatus error = null; + List createdPropertyValues = new ArrayList<>(); + for (ComponentInstanceProperty property : propertyValues) { + log.debug("Before adding property value {} toCI {}.", property.getName(), createdCapabilityInstance.getUniqueId()); + PropertyValueData propertyData = buildPropertyValueData(property.getName(), property.getType(), property.getValue(), createdCapabilityInstance.getUniqueId()); + Either addPropertyValueRes = addPropertyValueToCapabilityInstance(createdCapabilityInstance, propertyData, defaultProperties.get(property.getName())); + if (addPropertyValueRes.isRight()) { + error = addPropertyValueRes.right().value(); + log.debug("Failed to add property to capability instance {} ofRI. StatusIs {}.", createdCapabilityInstance.getUniqueId(), error); + break; + } else { + createdPropertyValues.add(addPropertyValueRes.left().value()); + } + log.debug("After adding property value {} toCI {} statusIs {}", property.getName(), createdCapabilityInstance.getUniqueId(), error); + } + if (error == null) { + return Either.left(createdPropertyValues); + } + return Either.right(error); + } + + private TitanOperationStatus addPropertyValuesToCapabilityInstance(TitanVertex createdCapabilityInstancevertex, List propertyValues, Map defaultProperties) { + TitanOperationStatus error = null; + String id = (String) titanGenericDao.getProperty(createdCapabilityInstancevertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + for (ComponentInstanceProperty property : propertyValues) { + log.trace("Before adding property value {} {} {}", property.getName(), toCI, id); + PropertyValueData propertyData = buildPropertyValueData(property.getName(), property.getType(), property.getValue(), id); + TitanOperationStatus addPropertyValueRes = addPropertyValueToCapabilityInstance(createdCapabilityInstancevertex, propertyData, defaultProperties.get(property.getName()), id); + if (!addPropertyValueRes.equals(TitanOperationStatus.OK)) { + error = addPropertyValueRes; + log.debug("Failed to add property to capability instance {} {} {} {}", id, ofRI, statusIs, error); + break; + } + log.debug("After adding property value {} {} {} {} {}", property.getName(), toCI, id, statusIs, error); + } + if (error == null) { + return TitanOperationStatus.OK; + } + return error; + } + + private PropertyValueData buildPropertyValueData(String propertyName, String propertyType, String propertyValue, String capabilityInstanceId) { + PropertyValueData propertyData = new PropertyValueData(); + String uniqueId = UniqueIdBuilder.buildPropertyValueUniqueId(capabilityInstanceId, propertyName); + Long creationTime = System.currentTimeMillis(); + propertyData.setUniqueId(uniqueId); + propertyData.setValue(propertyValue); + propertyData.setType(propertyType); + propertyData.setCreationTime(creationTime); + propertyData.setModificationTime(creationTime); + return propertyData; + } + + private Either addPropertyValueToCapabilityInstance(CapabilityInstData createdCapabilityInstance, PropertyValueData propertyValue, PropertyDefinition propertyDefinition) { + TitanOperationStatus error = null; + Map props = null; + Either createRelationRes; + PropertyValueData createdValue = null; + log.debug("Before creating property value node {} onGraph.", propertyValue.getUniqueId()); + Either createValueRes = titanGenericDao.createNode(propertyValue, PropertyValueData.class); + if (createValueRes.isRight()) { + error = createValueRes.right().value(); + log.debug("Failed to create property value for capability instance {} ofRI statusIs {}.", createdCapabilityInstance.getUniqueId(), error); + } + log.debug("After creating property value node {} onGraph statusIs {}.", propertyValue.getUniqueId(), error); + if (error == null) { + log.debug("Before creating relation from property value node {} toCI {}.", propertyValue.getUniqueId(), createdCapabilityInstance.getUniqueId()); + createdValue = createValueRes.left().value(); + props = new HashMap<>(); + props.put(GraphPropertiesDictionary.PROPERTY_NAME.name(), propertyDefinition.getName()); + props.put(GraphPropertiesDictionary.PROPERTY_ID.name(), propertyDefinition.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(createdCapabilityInstance, createdValue, GraphEdgeLabels.PROPERTY_VALUE, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to create relation from capability instance {} toValue {} statusIs {}.", createdCapabilityInstance.getUniqueId(), createdValue.getUniqueId(), error); + } + log.debug("After creating relation from property value node {} toCI {} statusIs {}.", propertyValue.getUniqueId(), createdCapabilityInstance.getUniqueId(), error); + } + if (error == null) { + log.debug("Before creating relation from property value node {} toProperty {}.", propertyValue.getUniqueId(), propertyDefinition.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(propertyValue, new PropertyData(propertyDefinition, null), GraphEdgeLabels.PROPERTY_IMPL, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to create relation from property value {} toProperty {} statusIs {}.", createdValue.getUniqueId(), propertyDefinition.getUniqueId(), error); + } + log.debug("After creating relation from property value node {} toProperty statusIs {}.", propertyValue.getUniqueId(), propertyDefinition.getUniqueId(), error); + } + if (error == null) { + return Either.left(createdValue); + } + return Either.right(error); + } + + private TitanOperationStatus addPropertyValueToCapabilityInstance(TitanVertex createdCapabilityInstanceVertex, PropertyValueData propertyValue, PropertyDefinition propertyDefinition, String id) { + TitanOperationStatus error = null; + Map props = null; + TitanOperationStatus createRelationRes; + log.trace("Before creating property value node {} on graph.", propertyValue.getUniqueId()); + Either createValueRes = titanGenericDao.createNode(propertyValue); + if (createValueRes.isRight()) { + error = createValueRes.right().value(); + if (log.isDebugEnabled()){ + log.debug("Failed to create property value for capability instance {} {} {} {}", id, ofRI, statusIs, error); + } + } + log.trace("After creating property value node {} on graph status is {}", propertyValue.getUniqueId(), error); + TitanVertex createdPropVertex = null; + String createdId = null; + if (error == null) { + log.trace("Before creating relation from property value node {} {} {} ", propertyValue.getUniqueId(), toCI, id); + props = new HashMap<>(); + props.put(GraphPropertiesDictionary.PROPERTY_NAME.name(), propertyDefinition.getName()); + props.put(GraphPropertiesDictionary.PROPERTY_ID.name(), propertyDefinition.getUniqueId()); + createdPropVertex = createValueRes.left().value(); + createRelationRes = titanGenericDao.createEdge(createdCapabilityInstanceVertex, createdPropVertex, GraphEdgeLabels.PROPERTY_VALUE, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + createdId = (String) titanGenericDao.getProperty(createdPropVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (log.isDebugEnabled()) { + log.debug("Failed to create relation from capability instance {} {} {} {} {}", id, toValue, createdId, statusIs, error); + } + } + if (log.isTraceEnabled()){ + log.trace("After creating relation from property value node {} {} {} {} {}", propertyValue.getUniqueId(), toCI, id, statusIs, error); + } + } + if (error == null) { + log.trace("Before creating relation from property value node {} {} {}", propertyValue.getUniqueId(), toProperty, propertyDefinition.getUniqueId()); + createRelationRes = titanGenericDao.createEdge(createdPropVertex, new PropertyData(propertyDefinition, null), GraphEdgeLabels.PROPERTY_IMPL, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + log.debug("Failed to create relation from property value {} {} {} {} {}", createdId, toProperty, propertyDefinition.getUniqueId(), statusIs, error); + } + log.debug("After creating relation from property value node {} {} {} {} {}", propertyValue.getUniqueId(), toProperty, propertyDefinition.getUniqueId(), statusIs, error); + } + if (error == null) { + return TitanOperationStatus.OK; + } + return error; + } + + private Either validateCapabilityInstanceProperties(Map defaultProperties, List propertyValues) { + Either result = Either.left(true); + for (ComponentInstanceProperty property : propertyValues) { + result = validateUpdateCapabilityInstancePropertyValue(property, defaultProperties); + if (result.isRight()) { + break; + } + } + return result; + } + + private Either validateUpdateCapabilityInstancePropertyValue(ComponentInstanceProperty property, Map defaultProperties) { + PropertyDefinition defaultProperty; + String propertyName = property.getName(); + Either result = null; + if (defaultProperties.containsKey(propertyName)) { + defaultProperty = defaultProperties.get(propertyName); + String propertyType = property.getType() == null || property.getType().isEmpty() ? defaultProperty.getType() : property.getType(); + + String innerType = null; + if (property.getSchema() != null && property.getSchema().getProperty() != null) + innerType = property.getSchema().getProperty().getType(); + if (innerType == null && defaultProperty.getSchema() != null && defaultProperty.getSchema().getProperty() != null) + innerType = defaultProperty.getSchema().getProperty().getType(); + + if (defaultProperty.getType().equals(propertyType)) { + String propertyValue = property.getValue(); + Either, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Failed to update property value statusIs {}.", status); + result = Either.right(status); + } + if (result == null) { + Either updatedPropertyValueRes = propertyOperation.validateAndUpdatePropertyValue(propertyType, propertyValue, innerType, allDataTypes.left().value()); + if (updatedPropertyValueRes.isLeft()) { + if (updatedPropertyValueRes.left().value() != null) + property.setDefaultValue(updatedPropertyValueRes.left().value().toString()); + result = Either.left(true); + } else { + result = Either.right(TitanOperationStatus.INVALID_PROPERTY); + } + } + log.debug("The property with name {} has invalid type {} or invalid value {}.", propertyName, propertyType, propertyValue); + + } else { + result = Either.right(TitanOperationStatus.PROPERTY_NAME_ALREADY_EXISTS); + log.debug("The property with name {} and different type already exists.", propertyName); + } + } else { + result = Either.right(TitanOperationStatus.NOT_FOUND); + log.debug("Failed to find property with name {}.", propertyName); + } + return result; + } + + /** + * validate capability instance uniqueness + * + * @param resourceInstanceId + * @param capabilityId + * @return + */ + @Override + public Either validateCapabilityInstExistence(String resourceInstanceId, String capabilityId) { + Either result = null; + TitanOperationStatus error; + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityId); + Either getCapabilityInstanceEdgeRes = titanGenericDao.getOutgoingEdgeByCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, GraphEdgeLabels.CAPABILITY_INST, props); + if (getCapabilityInstanceEdgeRes.isRight()) { + error = getCapabilityInstanceEdgeRes.right().value(); + if (error.equals(TitanOperationStatus.NOT_FOUND)) { + result = Either.left(false); + } else { + log.debug("Failed to get outgoing edge for resource instance {} statusIs {}.", resourceInstanceId, error); + result = Either.right(error); + } + } + if (result == null) { + result = Either.left(true); + } + return result; + } + + @Override + public Either validateCapabilityInstExistence(TitanVertex instanceVertex, String resourceInstanceId, String capabilityId) { + Either result = null; + TitanOperationStatus error; + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityId); + Either getCapabilityInstanceEdgeRes = titanGenericDao.getOutgoingEdgeByCriteria(instanceVertex, GraphEdgeLabels.CAPABILITY_INST, props); + if (getCapabilityInstanceEdgeRes.isRight()) { + error = getCapabilityInstanceEdgeRes.right().value(); + if (error.equals(TitanOperationStatus.NOT_FOUND)) { + result = Either.left(false); + } else { + log.debug("Failed to get outgoing edge for resource instance {} {} {}", resourceInstanceId, statusIs, error); + result = Either.right(error); + } + } + if (result == null) { + result = Either.left(true); + } + return result; + } + + private Either createCapabilityInstanceOnGraph(String resourceInstanceId, CapabilityData overrideCapabilityData, CapabilityInstData capabilityInstance) { + log.debug("Before creation of capability instance of capability {} forRI {}.", overrideCapabilityData.getUniqueId(), resourceInstanceId); + + Either createRelationRes; + CapabilityInstData createdCapabilityInstance = null; + String capabilityInstanceId = null; + TitanOperationStatus error = null; + Either createCapabilityInstanceRes = titanGenericDao.createNode(capabilityInstance, CapabilityInstData.class); + if (createCapabilityInstanceRes.isRight()) { + error = createCapabilityInstanceRes.right().value(); + log.debug("failedCreateCI {} forRI {} statusIs {}.", overrideCapabilityData.getUniqueId(), resourceInstanceId, error); + } + log.debug("After creation of capability instance of capability {} forRI {} statusIs {}.", overrideCapabilityData.getUniqueId(), resourceInstanceId, error); + if (error == null) { + createdCapabilityInstance = createCapabilityInstanceRes.left().value(); + capabilityInstanceId = createdCapabilityInstance.getUniqueId(); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), overrideCapabilityData.getUniqueId()); + UniqueIdData resourceInstanceIdData = new UniqueIdData(NodeTypeEnum.ResourceInstance, resourceInstanceId); + log.debug("Before associating resource instance {} to capability instance.", resourceInstanceId); + createRelationRes = titanGenericDao.createRelation(resourceInstanceIdData, capabilityInstance, GraphEdgeLabels.CAPABILITY_INST, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to assotiate resource instance {} toCI {} statusIs {}.", resourceInstanceId, capabilityInstanceId, error); + } + log.debug("After associating resource instance {} to CI {} statusIs {}.", resourceInstanceId, capabilityInstanceId, error); + } + if (error == null) { + log.debug("Before associating capability instance {} toCapability {}.", capabilityInstanceId, overrideCapabilityData.getUniqueId()); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), overrideCapabilityData.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(createdCapabilityInstance, overrideCapabilityData, GraphEdgeLabels.INSTANCE_OF, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to associate capability instance {} toCapability statusIs {}.", capabilityInstanceId, overrideCapabilityData.getUniqueId(), error); + } + log.debug("After associating capability instance {} toCapability statusIs {}.", capabilityInstanceId, overrideCapabilityData.getUniqueId(), error); + } + if (error == null) { + return createCapabilityInstanceRes; + } + return Either.right(error); + } + + private Either createCapabilityInstanceOnGraph(TitanVertex riVertex, String resourceInstanceId, TitanVertex overrideCapabilityDataVertex, CapabilityInstData capabilityInstance) { + String overrideCapabilityDataId = (String) titanGenericDao.getProperty(overrideCapabilityDataVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + log.trace("Before creation of capability instance of capability {} {} {}", overrideCapabilityDataVertex, forRI, resourceInstanceId); + + TitanOperationStatus createRelationRes; + TitanVertex createdCapabilityInstance = null; + String capabilityInstanceId = null; + TitanOperationStatus error = null; + Either createCapabilityInstanceRes = titanGenericDao.createNode(capabilityInstance); + if (createCapabilityInstanceRes.isRight()) { + error = createCapabilityInstanceRes.right().value(); + log.debug("Failed to create capability instance of capability {} {} {} {} {}", overrideCapabilityDataId, forRI, resourceInstanceId, statusIs, error); + } + log.trace("After creation of capability instance of capability {} {} {} {} {}", overrideCapabilityDataId, forRI, resourceInstanceId, statusIs, error); + if (error == null) { + createdCapabilityInstance = createCapabilityInstanceRes.left().value(); + capabilityInstanceId = (String) titanGenericDao.getProperty(createdCapabilityInstance, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), overrideCapabilityDataId); + log.debug("Before associating resource instance {} to capability instance.", resourceInstanceId); + + createRelationRes = titanGenericDao.createEdge(riVertex, capabilityInstance, GraphEdgeLabels.CAPABILITY_INST, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + log.debug("Failed to assotiate resource instance {} {} {} {} {}", resourceInstanceId, toCI, capabilityInstanceId, statusIs, error); + } + if (log.isTraceEnabled()) { + log.trace("After associating resource instance {} {} {} {} {}", resourceInstanceId, toCI, capabilityInstanceId, statusIs, error); + } + } + if (error == null) { + log.trace("Before associating capability instance {} {} {}", capabilityInstanceId, toCapability, overrideCapabilityDataId); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), overrideCapabilityDataId); + createRelationRes = titanGenericDao.createEdge(createdCapabilityInstance, overrideCapabilityDataVertex, GraphEdgeLabels.INSTANCE_OF, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + log.debug("Failed to associate capability instance {} {} {} {} {}", capabilityInstanceId, toCapability, overrideCapabilityDataId, statusIs, error); + } + log.debug("After associating capability instance {} {} {} {} {}", capabilityInstanceId, toCapability, overrideCapabilityDataId, statusIs, error); + } + if (error == null) { + return createCapabilityInstanceRes; + } + return Either.right(error); + } + + private CapabilityInstData buildCapabilityInstanceData(String resourceInstanceId, CapabilityDefinition capability) { + CapabilityInstData capabilityInstance = new CapabilityInstData(); + Long creationTime = System.currentTimeMillis(); + String uniqueId = UniqueIdBuilder.buildCapabilityInstanceUid(resourceInstanceId, capability.getName()); + + capabilityInstance.setCreationTime(creationTime); + capabilityInstance.setModificationTime(creationTime); + capabilityInstance.setUniqueId(uniqueId); + + return capabilityInstance; + } + + /** + * delete capability instance from resource instance + * + * @param resourceInstanceId + * @param capabilityInstanceId + * @return + */ + @Override + public Either deleteCapabilityInstanceFromResourceInstance(String resourceInstanceId, String capabilityInstanceId) { + log.debug("Before deleting of capability instance {} fromRI {}.", capabilityInstanceId, resourceInstanceId); + + Either deleteCapabilityInstRes = null; + TitanOperationStatus error = null; + Either deleteProperyValuesRes = deleteAllPropertyValuesOfCapabilityInstance(resourceInstanceId, capabilityInstanceId); + if (deleteProperyValuesRes.isRight()) { + error = deleteProperyValuesRes.right().value(); + log.debug("failedDeletePropertyValues {} for RI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + } + if (error == null) { + deleteCapabilityInstRes = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), capabilityInstanceId, CapabilityInstData.class); + if (deleteCapabilityInstRes.isRight()) { + error = deleteCapabilityInstRes.right().value(); + log.debug("Failed to delete capability instance {} forRI {} statusIs {}", capabilityInstanceId, resourceInstanceId, error); + } + } + log.debug("After deleting of capability instance {} fromRI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + if (error == null) { + return Either.left(deleteCapabilityInstRes.left().value()); + } + return Either.right(error); + } + + private Either deleteAllPropertyValuesOfCapabilityInstance(String resourceInstanceId, String capabilityInstanceId) { + log.debug("Before deleting all property values of capability instance {} fromRI {}.", capabilityInstanceId, resourceInstanceId); + TitanOperationStatus error = null; + List> deletePropertiesPairs; + Either>, TitanOperationStatus> getPropertyValuesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), capabilityInstanceId, + GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, PropertyValueData.class); + if (getPropertyValuesRes.isRight()) { + error = getPropertyValuesRes.right().value(); + log.debug("Failed to retrieve property values of capability instance {} forRI {} status {}.", capabilityInstanceId, resourceInstanceId, error); + } + if (error == null) { + deletePropertiesPairs = getPropertyValuesRes.left().value(); + for (ImmutablePair propertyPair : deletePropertiesPairs) { + Either deletePropertyRes = titanGenericDao.deleteNode(propertyPair.getLeft(), PropertyValueData.class); + if (deletePropertyRes.isRight()) { + error = deletePropertyRes.right().value(); + log.debug("failedDeletePropertyValues {} forRI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + break; + } + } + } + log.debug("After deleting all property values of capability instance {} fromRI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + if (error == null) { + return Either.left(true); + } + return Either.right(error); + } + + /** + * get all capability instances for resource instance returns all Capability Instances related to Resource Instance as List or TitanOperationStatus if error occurs or if Resource Instance have no any related Capability + * Instance + * + * @param resourceInstanceId + * @return Either, TitanOperationStatus> + */ + @Override + public Either>, TitanOperationStatus> getAllCapabilityInstancesOfResourceInstance(String resourceInstanceId) { + log.debug("Before deleting all capability instances of resource instance {}.", resourceInstanceId); + TitanOperationStatus error = null; + Either>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + if (getCapabilityInstancesRes.isRight()) { + error = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability Instances of resource instance {} statusIs {}.", resourceInstanceId, error); + } + log.debug("After deleting all capability instances of resource instance {} statusIs {}", resourceInstanceId, error); + if (error == null) { + return getCapabilityInstancesRes; + } + return Either.right(error); + } + + /** + * get capability instance of capability for resource instance + * + * @param resourceInstanceId + * @param capabilityId + * @return + */ + @Override + public Either getCapabilityInstanceOfCapabilityOfResourceInstance(String resourceInstanceId, String capabilityId) { + TitanOperationStatus error = null; + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityId); + Either, TitanOperationStatus> getCapabilityInstanceRes = titanGenericDao.getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class, props); + if (getCapabilityInstanceRes.isRight()) { + error = getCapabilityInstanceRes.right().value(); + log.debug("Failed to retrieve capability Instance of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + if (error == null) { + return Either.left(getCapabilityInstanceRes.left().value().getLeft()); + } + return Either.right(error); + } + + /** + * update capability property values + * + * @param resourceInstanceId + * @param propertyValues + * @param capabilityId + * @return + */ + @Override + public Either, TitanOperationStatus> updateCapabilityPropertyValues(String resourceInstanceId, String capabilityId, List propertyValues) { + log.debug("Before updating property values of capability {} ofRI {}.", capabilityId, resourceInstanceId); + TitanOperationStatus error = null; + Map props = new HashMap<>(); + CapabilityInstData capabilityInstance = null; + String capabilityInstanceId = null; + Either deleteProperyValuesRes; + + CapabilityData overrideCapabilityData; + CapabilityDefinition overrideCapabilityDefinition; + Map defaultProperties = null; + Either, TitanOperationStatus> getCapabilityDataRes = null; + Either, TitanOperationStatus> addPropertyValuesRes = null; + Either getCapabilityDefinitionRes = null; + + log.debug("Before getting all capability instances of RI {}.", resourceInstanceId); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityId); + Either, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class, props); + if (getCapabilityInstancesRes.isRight()) { + error = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability Instances of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + log.debug("After getting all capability instances ofRI {} statusIs {}.", resourceInstanceId, error); + if (error == null) { + log.debug("Before deleting all capability instances ofRI {}.", resourceInstanceId); + capabilityInstance = getCapabilityInstancesRes.left().value().getLeft(); + capabilityInstanceId = capabilityInstance.getUniqueId(); + deleteProperyValuesRes = deleteAllPropertyValuesOfCapabilityInstance(resourceInstanceId, capabilityInstanceId); + if (deleteProperyValuesRes.isRight()) { + error = deleteProperyValuesRes.right().value(); + log.debug("failedDeletePropertyValues {} forRI {} statusIs {}", capabilityInstanceId, resourceInstanceId, statusIs, error); + } + log.debug("After deleting all capability instances ofRI {} statusIs {}.", resourceInstanceId, error); + } + if (error == null) { + log.debug("Before getting capability {} ofRI {}.", capabilityId, resourceInstanceId); + getCapabilityDataRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class); + if (getCapabilityDataRes.isRight()) { + error = getCapabilityDataRes.right().value(); + log.debug("Failed to get capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + log.debug("After getting capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + if (error == null) { + log.debug("Before getting capability definition for capability {} ofRI {}.", capabilityId, resourceInstanceId); + overrideCapabilityData = getCapabilityDataRes.left().value().getLeft(); + getCapabilityDefinitionRes = capabilityOperation.getCapabilityByCapabilityData(overrideCapabilityData); + if (getCapabilityDefinitionRes.isRight()) { + error = getCapabilityDefinitionRes.right().value(); + log.debug("Failed to retrieve capability {} ofRI {} statusIs {}", capabilityId, resourceInstanceId, error); + } + log.debug("After getting capability definition for capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + if (error == null) { + log.debug("Before validating capability properties of capability instance {} ofRI {}.", capabilityInstanceId, resourceInstanceId); + overrideCapabilityDefinition = getCapabilityDefinitionRes.left().value(); + if (overrideCapabilityDefinition.getProperties() != null) { + defaultProperties = overrideCapabilityDefinition.getProperties().stream().collect(Collectors.toMap(PropertyDefinition::getName, Function.identity())); + } + Either result = validateCapabilityInstanceProperties(defaultProperties, propertyValues); + if (result.isRight()) { + error = result.right().value(); + log.debug("failedAddProperties {} ofRI {} statusIs {}.", capabilityInstance.getUniqueId(), resourceInstanceId, error); + } + log.debug("After validating capability properties of capability instance {} of RI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + } + if (error == null) { + log.debug("Before adding property values toCI {} ofRI {}.", capabilityInstanceId, resourceInstanceId); + addPropertyValuesRes = addPropertyValuesToCapabilityInstance(capabilityInstance, propertyValues, defaultProperties); + if (addPropertyValuesRes.isRight()) { + error = addPropertyValuesRes.right().value(); + log.debug("failedAddProperties {} ofRI {} statusIs {}.", capabilityInstance.getUniqueId(), resourceInstanceId, error); + } + log.debug("Before adding property values toCI {} ofRI {}.", capabilityInstanceId, resourceInstanceId); + } + log.debug("After updating property values of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + if (error == null) { + return addPropertyValuesRes; + } + return Either.right(error); + } + + /** + * clone and associate capability instance with property values + * + * @param createdComponentInstance + * @param capability + * @param capabilityInstPair + * @return + */ + @Override + public Either>, TitanOperationStatus> cloneAssociateCapabilityInstanceWithPropertyValues(ComponentInstanceData createdComponentInstance, CapabilityDefinition capability, + ImmutablePair capabilityInstPair) { + + TitanOperationStatus error = null; + String componentInstanceId = createdComponentInstance.getUniqueId(); + String capabilityInstanceId = capabilityInstPair.getLeft().getUniqueId(); + + log.debug("Before cloning capability instance with property values of capability instance {} ofRI {}.", capabilityInstanceId, componentInstanceId); + List> propertyValuePairs; + List newPropertyValues = new ArrayList<>(); + CapabilityInstData cloneCapabilityInstance = null; + Either cloneCapabilityInstanceNodeRes = null; + + log.debug("Before getting all property values ofCI {} ofRI {}.", capabilityInstanceId, componentInstanceId); + Either>, TitanOperationStatus> getPropertyValuesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), capabilityInstPair.getLeft().getUniqueId(), + GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, PropertyValueData.class); + if (getPropertyValuesRes.isRight()) { + error = getPropertyValuesRes.right().value(); + log.debug("Failed to retrieve property values of capability instance {} ofCI {} statusIs {}.", capabilityInstPair.getLeft().getUniqueId(), componentInstanceId ,error); + } + log.debug("After getting all property values ofCI {} ofRI {} statusIs {}.", capabilityInstanceId, componentInstanceId, error); + if (error == null) { + CapabilityInstData cloneCapabilityInst = buildCapabilityInstanceData(componentInstanceId, capability); + log.debug("Before creating capability instance node {} onGraph.", cloneCapabilityInst.getUniqueId()); + cloneCapabilityInstanceNodeRes = titanGenericDao.createNode(cloneCapabilityInst, CapabilityInstData.class); + if (cloneCapabilityInstanceNodeRes.isRight()) { + error = cloneCapabilityInstanceNodeRes.right().value(); + log.debug("Failed to create capability instance of capability {} ofCI {} statusIs {}.", capability.getUniqueId(), componentInstanceId, error); + } + log.debug("After creating capability instance node {} onGraph. statusIs {}", cloneCapabilityInst.getUniqueId(), error); + } + + if (error == null) { + log.debug("Before creating relation from capability instance {} toCapability {} onGraph.", cloneCapabilityInstanceNodeRes.left().value().getUniqueId(), capability.getUniqueId()); + cloneCapabilityInstance = cloneCapabilityInstanceNodeRes.left().value(); + CapabilityData capabilityData = buildCapabilityData(capability); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityData.getUniqueId()); + Either createRelationRes = titanGenericDao.createRelation(cloneCapabilityInstance, capabilityData, GraphEdgeLabels.INSTANCE_OF, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to associate capability instance {} toCapability {} statusIs {}.", cloneCapabilityInstance.getUniqueId(), capability.getUniqueId(), error); + } + log.debug("After creating relation from capability instance {} toCapability {} onGraph. statusIs {}.", cloneCapabilityInstanceNodeRes.left().value().getUniqueId(), capability.getUniqueId(), error); + } + + if (error == null) { + log.debug("Before cloning property values ofCI {}.", capabilityInstanceId); + propertyValuePairs = getPropertyValuesRes.left().value(); + for (ImmutablePair propertyValuePair : propertyValuePairs) { + Either clonePropertyValueRes = cloneAssociatePropertyValue(cloneCapabilityInstance, propertyValuePair); + if (clonePropertyValueRes.isRight()) { + error = clonePropertyValueRes.right().value(); + if (log.isDebugEnabled()) { + log.debug("Failed to clone property value {} ofCapability {} ofCI {}. statusIs {}.", propertyValuePair.getLeft().getUniqueId(), capability.getUniqueId(), componentInstanceId, error); + } + break; + } else { + newPropertyValues.add(clonePropertyValueRes.left().value()); + } + } + log.debug("After cloning property values of CI {} statusIs {}.", capabilityInstanceId, error); + } + log.debug("After cloning capability instance with property values of capability instance {} ofRI {} statusIs {}.", capabilityInstanceId, componentInstanceId, error); + if (error == null) { + return Either.left(new ImmutablePair>(cloneCapabilityInstance, newPropertyValues)); + } + return Either.right(error); + } + + public Either cloneAssociateCapabilityInstanceWithPropertyValues(TitanVertex componentInstanceVertex, CapabilityDefinition capability, ImmutablePair capabilityInstPair) { + + TitanOperationStatus error = null; + String componentInstanceId = (String) titanGenericDao.getProperty(componentInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String capabilityInstanceId = capabilityInstPair.getLeft().getUniqueId(); + + if (log.isTraceEnabled()) { + log.trace("Before cloning capability instance with property values of capability instance {} {} {}", capabilityInstanceId, ofRI, componentInstanceId); + } + List> propertyValuePairs; + Either cloneCapabilityInstanceNodeRes = null; + + if (log.isTraceEnabled()) { + log.trace("Before getting all property values {} {} {} {}", ofCI, capabilityInstanceId, ofRI, componentInstanceId); + } + Either>, TitanOperationStatus> getPropertyValuesRes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), capabilityInstPair.getLeft().getUniqueId(), + GraphEdgeLabels.PROPERTY_VALUE); + if (getPropertyValuesRes.isRight()) { + error = getPropertyValuesRes.right().value(); + if (log.isDebugEnabled()) { + log.debug("Failed to retrieve property values of capability instance {} {} {} {} {}", capabilityInstPair.getLeft().getUniqueId(), ofCI, componentInstanceId, statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After getting all property values {} {} {} {} {} {}", ofCI, capabilityInstanceId, ofRI, componentInstanceId, statusIs, error); + } + if (error == null) { + CapabilityInstData cloneCapabilityInst = buildCapabilityInstanceData(componentInstanceId, capability); + log.trace("Before creating capability instance node {} {} ", cloneCapabilityInst.getUniqueId(), onGraph); + cloneCapabilityInstanceNodeRes = titanGenericDao.createNode(cloneCapabilityInst); + if (cloneCapabilityInstanceNodeRes.isRight()) { + error = cloneCapabilityInstanceNodeRes.right().value(); + if (log.isDebugEnabled()) { + log.debug("Failed to create capability instance of capability {} {} {} {} {}", capability.getUniqueId(), ofCI, componentInstanceId, statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After creating capability instance node {} {} {} {}", cloneCapabilityInst.getUniqueId(), onGraph, statusIs, error); + } + } + CapabilityData capabilityData; + TitanVertex cloneCapabilityInstance = null; + if (error == null) { + if (log.isTraceEnabled()) { + log.trace("Before creating relation from capability instance {} {} {} {}", capability.getUniqueId(), toCapability, capability.getUniqueId(), onGraph); + } + capabilityData = buildCapabilityData(capability); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityData.getUniqueId()); + cloneCapabilityInstance = cloneCapabilityInstanceNodeRes.left().value(); + TitanOperationStatus createRelationRes = titanGenericDao.createEdge(cloneCapabilityInstance, capabilityData, GraphEdgeLabels.INSTANCE_OF, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + if (log.isDebugEnabled()) { + log.debug("Failed to associate capability instance {} {} {} {} {}", capabilityData.getUniqueId(), toCapability, capability.getUniqueId(), statusIs, createRelationRes); + } + } + if (log.isTraceEnabled()) { + log.trace("After creating relation from capability instance {} {} {} {} {} {}", capabilityData.getUniqueId(), toCapability, capability.getUniqueId(), onGraph, statusIs, error); + } + } + + if (error == null) { + log.trace("Before cloning property values {} {} ", ofCI, capabilityInstanceId); + propertyValuePairs = getPropertyValuesRes.left().value(); + for (ImmutablePair propertyValuePair : propertyValuePairs) { + TitanOperationStatus clonePropertyValueRes = cloneAssociatePropertyValue(cloneCapabilityInstance, propertyValuePair); + if (!clonePropertyValueRes.equals(TitanOperationStatus.OK)) { + error = clonePropertyValueRes; + if (log.isDebugEnabled()) { + log.debug("Failed to clone property value of capability {} {} {} {} {}", capability.getUniqueId(), ofCI, componentInstanceId, statusIs, error); + } + break; + } + } + if (log.isDebugEnabled()) { + log.debug("After cloning property values {} {} {} {}", ofCI, capabilityInstanceId, statusIs, error); + } + } + log.debug("After cloning capability instance with property values of capability instance {} ofRI {} statusIs {}.", capabilityInstanceId, componentInstanceId, error); + if (error == null) { + return Either.left(cloneCapabilityInstance); + } + return Either.right(error); + } + + private CapabilityData buildCapabilityData(CapabilityDefinition capability) { + CapabilityData capabilityData = new CapabilityData(); + capabilityData.setUniqueId(capability.getUniqueId()); + capabilityData.setDescription(capability.getDescription()); + capabilityData.setType(capability.getType()); + capabilityData.setMaxOccurrences(capability.getMaxOccurrences()); + capabilityData.setMinOccurrences(capability.getMinOccurrences()); + List validSourceTypes = capability.getValidSourceTypes(); + if (validSourceTypes != null) { + capabilityData.setValidSourceTypes(validSourceTypes); + } + return capabilityData; + } + + private Either cloneAssociatePropertyValue(CapabilityInstData cloneCapabilityInstance, ImmutablePair propertyValuePair) { + TitanOperationStatus error = null; + String propertyValueID = propertyValuePair.getLeft().getUniqueId(); + String capabilityInstanceId = cloneCapabilityInstance.getUniqueId(); + log.debug("Before cloning property values {} ofCI {}.", propertyValueID, capabilityInstanceId); + + Map props = propertyValuePair.getRight().getProperties(); + PropertyData propertyData = new PropertyData(); + String propertyId = (String) props.get(GraphPropertiesDictionary.PROPERTY_ID.name()); + propertyData.getPropertyDataDefinition().setUniqueId(propertyId); + + PropertyValueData propertyValue = buildPropertyValueData((String) props.get(GraphPropertiesDictionary.PROPERTY_NAME.name()), propertyValuePair.getLeft().getType(), propertyValuePair.getLeft().getValue(), capabilityInstanceId); + PropertyValueData createdValue = null; + Either createRelationRes; + + log.debug("Before creating property values node {} onGraph.", propertyValue.getUniqueId()); + Either createValueRes = titanGenericDao.createNode(propertyValue, PropertyValueData.class); + if (createValueRes.isRight()) { + error = createValueRes.right().value(); + log.debug("Failed to create property value for capability instance {} ofRI. statusIs {}.", cloneCapabilityInstance.getUniqueId(), error); + } + log.debug("After creating property values node {} onGraph. statusIs {}.", propertyValue.getUniqueId(), error); + if (error == null) { + createdValue = createValueRes.left().value(); + log.debug("Before creating relation from capability instance {} toValue {}.", capabilityInstanceId, createdValue.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(cloneCapabilityInstance, createdValue, GraphEdgeLabels.PROPERTY_VALUE, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to create relation from capability instance {} toValue {} statusIs {}.", cloneCapabilityInstance.getUniqueId(), createdValue.getUniqueId(), error); + } + log.debug("After creating relation from capability instance {} toValue {} statusIs {}", capabilityInstanceId, createdValue.getUniqueId(), error); + } + if (error == null) { + log.debug("Before creating relation from property value {} toProperty {}.", createdValue, propertyData.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(createdValue, propertyData, GraphEdgeLabels.PROPERTY_IMPL, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to create relation from property value {} toProperty {} statusIs {}.", createdValue.getUniqueId(), propertyId, error); + } + log.debug("Before creating relation from property value {} toProperty {} statusIs {}.", createdValue, propertyData.getUniqueId(), error); + } + log.debug("After cloning property values {} ofCI {} statusIs {}.", propertyValueID, capabilityInstanceId, error); + if (error == null) { + return Either.left(createdValue); + } + return Either.right(error); + } + + private TitanOperationStatus cloneAssociatePropertyValue(TitanVertex capabilityInstanceVertex, ImmutablePair propertyValuePair) { + TitanOperationStatus error = null; + TitanVertex propertyVertex = propertyValuePair.getLeft(); + String propertyValueID = (String) titanGenericDao.getProperty(propertyVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String capabilityInstanceId = (String) titanGenericDao.getProperty(capabilityInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (log.isTraceEnabled()) { + log.trace("Before cloning property values {} {} {}", propertyValueID, ofCI, capabilityInstanceId); + } + + Map props = titanGenericDao.getProperties(propertyValuePair.getRight()); + PropertyData propertyData = new PropertyData(); + String propertyId = (String) props.get(GraphPropertiesDictionary.PROPERTY_ID.name()); + propertyData.getPropertyDataDefinition().setUniqueId(propertyId); + + String propertyType = (String) titanGenericDao.getProperty(propertyVertex, GraphPropertiesDictionary.TYPE.getProperty()); + String propertyValueStr = (String) titanGenericDao.getProperty(propertyVertex, GraphPropertiesDictionary.VALUE.getProperty()); + + PropertyValueData propertyValue = buildPropertyValueData((String) props.get(GraphPropertiesDictionary.PROPERTY_NAME.name()), propertyType, propertyValueStr, capabilityInstanceId); + TitanVertex createdValue = null; + TitanOperationStatus createRelationRes; + + log.trace("Before creating property values node {} {} ", propertyValue.getUniqueId(), onGraph); + Either createValueRes = titanGenericDao.createNode(propertyValue); + String capabiltyInstId = (String) titanGenericDao.getProperty(capabilityInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (createValueRes.isRight()) { + error = createValueRes.right().value(); + if (log.isDebugEnabled()) { + log.debug("Failed to create property value for capability instance {} {} {} {}", capabiltyInstId, ofRI, statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After creating property values node {} {} {} {} ", propertyValue.getUniqueId(), onGraph, statusIs, error); + } + if (error == null) { + createdValue = createValueRes.left().value(); + log.trace("Before creating relation from capability instance {} {} {}", capabilityInstanceId, toValue, propertyValue.getUniqueId()); + createRelationRes = titanGenericDao.createEdge(capabilityInstanceVertex, createdValue, GraphEdgeLabels.PROPERTY_VALUE, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + if (log.isDebugEnabled()) { + log.debug("Failed to create relation from capability instance {} {} {} {} {}", capabiltyInstId, toValue, propertyValue.getUniqueId(), statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After creating relation from capability instance {} {} {} {} {} ", capabilityInstanceId, toValue, propertyValue.getUniqueId(), statusIs, error); + } + } + if (error == null) { + log.trace("Before creating relation from property value {} {} {} ", createdValue, toProperty, propertyData.getUniqueId()); + createRelationRes = titanGenericDao.createEdge(createdValue, propertyData, GraphEdgeLabels.PROPERTY_IMPL, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + if (log.isDebugEnabled()) { + log.debug("Failed to create relation from property value {} {} {} {} {}", propertyValue.getUniqueId(), toProperty, propertyId, statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("Before creating relation from property value c", createdValue, toProperty, propertyData.getUniqueId(), statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After cloning property values {} {} {} {} {}", propertyValueID, ofCI, capabilityInstanceId, statusIs, error); + } + if (error == null) { + return TitanOperationStatus.OK; + } + return error; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java new file mode 100644 index 0000000000..9f00674780 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java @@ -0,0 +1,1196 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +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.stream.Collectors; + +import org.antlr.misc.Graph; +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.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +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.components.ComponentMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +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.operations.api.ICapabilityOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.annotation.JsonAppend.Prop; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@Component("capability-operation") +public class CapabilityOperation extends AbstractOperation implements ICapabilityOperation { + + public CapabilityOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(CapabilityOperation.class.getName()); + + @Autowired + private PropertyOperation propertyOperation; + + @Autowired + private TitanGenericDao titanGenericDao; + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either addCapability(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition, boolean inTransaction) { + + Either result = null; + + try { + + Either addCapStatus = addCapabilityToResource(resourceId, capabilityName, capabilityDefinition); + + if (addCapStatus.isRight()) { + log.debug("Failed to add capability {} [ {} ] to graph", capabilityName, capabilityDefinition); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add Capability", capabilityName, String.valueOf(addCapStatus.right().value())); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addCapStatus.right().value())); + return result; + } else { + CapabilityData capabilityData = addCapStatus.left().value(); + + String capabilityUid = capabilityData.getUniqueId(); + Either capabilityRes = getCapability(capabilityUid, true); + log.debug("After fetching capability {} with uid {}. Status is {}", capabilityName, capabilityUid, capabilityRes); + + if (capabilityRes.isRight()) { + StorageOperationStatus status = capabilityRes.right().value(); + log.debug("Failed to fetch capability {] with uid {}. Status is {}", capabilityName, capabilityUid, status); + result = Either.right(status); + return result; + } + + CapabilityDefinition value = capabilityRes.left().value(); + log.debug("The returned CapabilityDefinition is {}", value); + result = Either.left(value); + + return result; + } + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public StorageOperationStatus addCapability(TitanVertex metadataVertex, String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition, boolean inTransaction) { + + StorageOperationStatus result = StorageOperationStatus.OK; + try { + + TitanOperationStatus addCapStatus = addCapabilityToResource(metadataVertex, resourceId, capabilityName, capabilityDefinition); + + if (!addCapStatus.equals(TitanOperationStatus.OK)) { + log.debug("Failed to add capability {} [ {} ]", capabilityName, capabilityDefinition); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add Capability", capabilityName, String.valueOf(addCapStatus)); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(addCapStatus); + } + } finally { + if (false == inTransaction) { + if (result == null || !result.equals(TitanOperationStatus.OK)) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + return result; + } + + private CapabilityDefinition convertCDataToCDefinition(CapabilityData capabilityData) { + + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setType(capabilityData.getType()); + + // TODO esofer do something + + return capabilityDefinition; + } + + @Override + public Either getCapability(String uniqueId) { + + return getCapability(uniqueId, false); + } + + public Either, StorageOperationStatus> getAllCapabilitiesOfResource(String resourceId, boolean recursively, boolean inTransaction) { + + Map capabilities = new HashMap<>(); + Either, StorageOperationStatus> result = null; + Set caseInsensitiveCapabilityNames = new HashSet<>(); + + try { + TitanOperationStatus status = getAllCapabilitiesRecusive(NodeTypeEnum.Resource, resourceId, recursively, capabilities, caseInsensitiveCapabilityNames, inTransaction); + if (!status.equals(TitanOperationStatus.OK)) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + result = Either.left(capabilities); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public TitanOperationStatus getAllCapabilitiesRecusive(NodeTypeEnum nodeType, String resourceId, boolean recursively, Map capabilities, Set caseInsensitiveCapabilityNames, boolean inTransaction) { + + TitanOperationStatus findStatus; + + if (recursively) { + findStatus = findAllCapabilitiesRecursively(resourceId, capabilities, caseInsensitiveCapabilityNames); + + } else { + findStatus = getCapabilitisOfResourceOnly(resourceId, capabilities, caseInsensitiveCapabilityNames); + } + if (!findStatus.equals(TitanOperationStatus.OK)) { + return findStatus; + } + + List derivedFromList = new ArrayList<>(); + TitanOperationStatus fillResourceDerivedListFromGraph = fillResourceDerivedListFromGraph(resourceId, derivedFromList); + if (!fillResourceDerivedListFromGraph.equals(TitanOperationStatus.OK)) { + log.debug("fail to find all valid sources of capability. status = {}", fillResourceDerivedListFromGraph.name()); + return fillResourceDerivedListFromGraph; + } + capabilities.forEach((name, capability) -> capability.setCapabilitySources(derivedFromList)); + return TitanOperationStatus.OK; + } + + protected TitanOperationStatus findAllCapabilitiesRecursively(String resourceId, Map capabilities, Set caseInsensitiveCapabilityNames) { + + TitanOperationStatus resourceCapabilitiesStatus = getCapabilitisOfResourceOnly(resourceId, capabilities, caseInsensitiveCapabilityNames); + + if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) { + return resourceCapabilitiesStatus; + } + + Either, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, + ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (!parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("Failed to find parent capabilities of resource {}. status is {}", resourceId, parentNodesStatus); + BeEcompErrorManager.getInstance().logBeFailedFindParentError("Fetch parent capabilities", resourceId, String.valueOf(parentNodesStatus)); + return parentNodesStatus; + } + } + if (parentNodes.isLeft()) { + ImmutablePair parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findAllCapabilitiesRecursively(parentUniqueId, capabilities, caseInsensitiveCapabilityNames); + + if (addParentIntStatus != TitanOperationStatus.OK) { + log.debug("Failed to fetch all capabilities of resource {}", parentUniqueId); + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + } + + private TitanOperationStatus getCapabilitisOfResourceOnly(String resourceId, Map capabilities, Set caseInsensitiveCapabilityNames) { + Either>, TitanOperationStatus> allCapabilitiesRes = getAllCapabilitiesPairs(resourceId); + if (allCapabilitiesRes.isRight()) { + TitanOperationStatus status = allCapabilitiesRes.right().value(); + log.debug("After fetching all capabilities of resource {}. status is {}", resourceId, status); + if (status.equals(TitanOperationStatus.NOT_FOUND)) { + status = TitanOperationStatus.OK; + } + return status; + } + + List> capabilityPairs = allCapabilitiesRes.left().value(); + + if (capabilityPairs != null) { + for (ImmutablePair capabilityPair : capabilityPairs) { + CapabilityData capabilityData = capabilityPair.getKey(); + GraphEdge graphEdge = capabilityPair.getValue(); + Map edgeProps = graphEdge.getProperties(); + if (edgeProps != null) { + String capabilityName = (String) edgeProps.get(GraphPropertiesDictionary.NAME.getProperty()); + if (capabilityName == null) { + log.error("Capability name was not found for capability {}", capabilityData.getUniqueId()); + return TitanOperationStatus.INVALID_ELEMENT; + } + Either capabilityDefRes = getCapabilityByCapabilityData(capabilityData); + if (capabilityDefRes.isRight()) { + TitanOperationStatus status = capabilityDefRes.right().value(); + return status; + } + CapabilityDefinition capabilityDefinition = capabilityDefRes.left().value(); + capabilityDefinition.setOwnerId(resourceId); + log.debug("Before adding capability {} with definition {} to result.", capabilityName, capabilityDefinition); + // US631462 + if (caseInsensitiveCapabilityNames.contains(capabilityName.toLowerCase())) { + log.debug("The capability {} was already defined in derived resource (case insensitive). Ignore {} from resource {}", capabilityName, capabilityName, resourceId); + } else { + capabilities.put(capabilityName, capabilityDefinition); + caseInsensitiveCapabilityNames.add(capabilityName.toLowerCase()); + } + } else { + log.debug("Capability name was not found for capability {}", capabilityData.getUniqueId()); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityData.getUniqueId(), String.valueOf(TitanOperationStatus.INVALID_ELEMENT)); + return TitanOperationStatus.INVALID_ELEMENT; + } + + } + } + return TitanOperationStatus.OK; + } + + @Override + public Either getCapability(String uniqueId, boolean inTransaction) { + + Either result = null; + + try { + Either capabiltyRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), uniqueId, CapabilityData.class); + if (capabiltyRes.isRight()) { + TitanOperationStatus status = capabiltyRes.right().value(); + log.debug("Failed to retrieve capability {} from graph. Status is {}", uniqueId, status); + + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", uniqueId, String.valueOf(status)); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + CapabilityData capabilityData = capabiltyRes.left().value(); + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setDescription(capabilityData.getDescription()); + capabilityDefinition.setUniqueId(capabilityData.getUniqueId()); + capabilityDefinition.setValidSourceTypes(capabilityData.getValidSourceTypes()); + capabilityDefinition.setMinOccurrences(capabilityData.getMinOccurrences()); + capabilityDefinition.setMaxOccurrences(capabilityData.getMaxOccurrences()); + + Either capabilityTypeRes = getCapabilityTypeOfCapability(uniqueId); + if (capabilityTypeRes.isRight()) { + TitanOperationStatus status = capabilityTypeRes.right().value(); + log.debug("Failed to retrieve capability type of capability {}. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", uniqueId, String.valueOf(status)); + + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + CapabilityTypeData capabilityTypeData = capabilityTypeRes.left().value(); + capabilityDefinition.setType(capabilityTypeData.getCapabilityTypeDataDefinition().getType()); + + Either, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), uniqueId, GraphEdgeLabels.CAPABILITY, + NodeTypeEnum.Resource, ResourceMetadataData.class); + if (parentNode.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentNode.right().value())); + } else { + ImmutablePair pair = parentNode.left().value(); + capabilityDefinition.setOwnerId(pair.left.getMetadataDataDefinition().getUniqueId()); + List derivedFromList = new ArrayList<>(); + // derivedFromList.add(pair.left.getMetadataDataDefinition().getName()); + TitanOperationStatus fillResourceDerivedListFromGraph = fillResourceDerivedListFromGraph(pair.left.getMetadataDataDefinition().getUniqueId(), derivedFromList); + if (fillResourceDerivedListFromGraph.equals(TitanOperationStatus.OK)) { + capabilityDefinition.setCapabilitySources(derivedFromList); + } + } + + Either, TitanOperationStatus> getPropertiesRes = getPropertiesOfCapability(uniqueId, capabilityTypeData.getCapabilityTypeDataDefinition().getType()); + if (getPropertiesRes.isRight() && !getPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = getPropertiesRes.right().value(); + log.debug("Failed to retrieve properties of capability {}. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Properties of Capability", uniqueId, String.valueOf(status)); + + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + if (getPropertiesRes.isLeft()) { + List properties = new ArrayList<>(); + for (PropertyDefinition property : getPropertiesRes.left().value()) { + properties.add(new ComponentInstanceProperty(property, null, null)); + } + capabilityDefinition.setProperties(properties); + } + result = Either.left(capabilityDefinition); + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private TitanOperationStatus fillResourceDerivedListFromGraph(String uniqueId, List derivedFromList) { + + Either resourceNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, ResourceMetadataData.class); + + if (resourceNode.isRight()) { + TitanOperationStatus parentNodesStatus = resourceNode.right().value(); + if (!parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("Failed to find resource {} . status is {}", uniqueId, parentNodesStatus); + return parentNodesStatus; + } + } + + derivedFromList.add(((ResourceMetadataDataDefinition) resourceNode.left().value().getMetadataDataDefinition()).getToscaResourceName()); + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (childrenNodes.isRight() && (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND)) { + return childrenNodes.right().value(); + } else if (childrenNodes.isLeft()) { + + List> pairList = childrenNodes.left().value(); + for (ImmutablePair pair : pairList) { + return fillResourceDerivedListFromGraph(pair.left.getMetadataDataDefinition().getUniqueId(), derivedFromList); + } + } + return TitanOperationStatus.OK; + } + + public Either getCapabilityByCapabilityData(CapabilityData capabilityData) { + + Either result; + + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setDescription(capabilityData.getDescription()); + capabilityDefinition.setUniqueId(capabilityData.getUniqueId()); + capabilityDefinition.setValidSourceTypes(capabilityData.getValidSourceTypes()); + capabilityDefinition.setMinOccurrences(capabilityData.getMinOccurrences()); + capabilityDefinition.setMaxOccurrences(capabilityData.getMaxOccurrences()); + + String capabilityUid = capabilityData.getUniqueId(); + Either capabilityTypeRes = getCapabilityTypeOfCapability(capabilityUid); + if (capabilityTypeRes.isRight()) { + TitanOperationStatus status = capabilityTypeRes.right().value(); + log.debug("Failed to retrieve capability type of capability {} . status is {}", capabilityUid, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityUid, String.valueOf(status)); + + return Either.right(status); + } + + CapabilityTypeData capabilityTypeData = capabilityTypeRes.left().value(); + capabilityDefinition.setType(capabilityTypeData.getCapabilityTypeDataDefinition().getType()); + + Either, TitanOperationStatus> capabilityPropertiesRes = getPropertiesOfCapability(capabilityUid, capabilityDefinition.getType()); + if (capabilityPropertiesRes.isRight() && !capabilityPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = capabilityPropertiesRes.right().value(); + log.debug("Failed to retrieve properties of capability {} . status is {}", capabilityUid, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityUid, String.valueOf(status)); + + result = Either.right(status); + return result; + } + if (capabilityPropertiesRes.isLeft()) { + List properties = new ArrayList<>(); + for (PropertyDefinition property : capabilityPropertiesRes.left().value()) { + properties.add(new ComponentInstanceProperty(property, null, null)); + } + capabilityDefinition.setProperties(properties); + } + result = Either.left(capabilityDefinition); + return result; + } + + public Either getCapabilityByCapabilityData(TitanVertex capabilityDataVertex) { + + Either result; + + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + Map props = titanGenericDao.getProperties(capabilityDataVertex); + CapabilityData capabilityData = GraphElementFactory.createElement((String) props.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, props, CapabilityData.class); + capabilityDefinition.setDescription(capabilityData.getDescription()); + capabilityDefinition.setUniqueId(capabilityData.getUniqueId()); + capabilityDefinition.setValidSourceTypes(capabilityData.getValidSourceTypes()); + capabilityDefinition.setMinOccurrences(capabilityData.getMinOccurrences()); + capabilityDefinition.setMaxOccurrences(capabilityData.getMaxOccurrences()); + + String capabilityUid = capabilityData.getUniqueId(); + Either capabilityTypeRes = getCapabilityTypeOfCapability(capabilityUid); + if (capabilityTypeRes.isRight()) { + TitanOperationStatus status = capabilityTypeRes.right().value(); + log.debug("Failed to retrieve capability type of capability {} . status is {}", capabilityUid, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityUid, String.valueOf(status)); + + return Either.right(status); + } + + CapabilityTypeData capabilityTypeData = capabilityTypeRes.left().value(); + capabilityDefinition.setType(capabilityTypeData.getCapabilityTypeDataDefinition().getType()); + + Either, TitanOperationStatus> capabilityPropertiesRes = getPropertiesOfCapability(capabilityUid, capabilityDefinition.getType()); + if (capabilityPropertiesRes.isRight() && !capabilityPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = capabilityPropertiesRes.right().value(); + log.debug("Failed to retrieve properties of capability {} . status is {}", capabilityUid, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityUid, String.valueOf(status)); + + result = Either.right(status); + return result; + } + if (capabilityPropertiesRes.isLeft()) { + List properties = new ArrayList<>(); + for (PropertyDefinition property : capabilityPropertiesRes.left().value()) { + properties.add(new ComponentInstanceProperty(property, null, null)); + } + capabilityDefinition.setProperties(properties); + } + result = Either.left(capabilityDefinition); + return result; + } + + public Either, TitanOperationStatus> getPropertiesOfCapability(String capabilityUid, String capabilityType) { + log.debug("Before getting properties of capability {} from graph ", capabilityUid); + + List properties; + Either, TitanOperationStatus> result = null; + Either, TitanOperationStatus> getPropertiesOfCapabilityTypeRes = null; + Either>, TitanOperationStatus> getPropertiesOfCapabilityRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, GraphEdgeLabels.PROPERTY, + NodeTypeEnum.Property, PropertyData.class); + if (getPropertiesOfCapabilityRes.isRight() && !getPropertiesOfCapabilityRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = getPropertiesOfCapabilityRes.right().value(); + log.debug("failed to get properties of capability with id {}. status={}", capabilityUid, status); + result = Either.right(status); + } + if (result == null) { + String capabilityTypeUid = UniqueIdBuilder.buildCapabilityTypeUid(capabilityType); + getPropertiesOfCapabilityTypeRes = getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeUid); + if (getPropertiesOfCapabilityTypeRes.isRight() && !getPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = getPropertiesOfCapabilityTypeRes.right().value(); + log.error("Failed to retrieve properties for capability type {} from graph. Status is {}", capabilityType, status); + result = Either.right(status); + } + } + if (result == null) { + result = getPropertiesOfCapabilityTypeRes.isRight() + ? (getPropertiesOfCapabilityRes.isRight() ? Either.right(TitanOperationStatus.NOT_FOUND) + : Either.left(getPropertiesOfCapabilityRes.left().value().stream().map(p -> propertyOperation.convertPropertyDataToPropertyDefinition(p.getKey(), null, capabilityUid)).collect(Collectors.toList()))) + : (getPropertiesOfCapabilityRes.isRight() ? Either.left(getPropertiesOfCapabilityTypeRes.left().value().values().stream().collect(Collectors.toList())) : null); + } + if (result == null) { + Map propertiesOfCapabilityType = getPropertiesOfCapabilityTypeRes.left().value(); + properties = getPropertiesOfCapabilityRes.left().value().stream() + .map(p -> propertyOperation.convertPropertyDataToPropertyDefinition(p.getKey(), (String) p.getRight().getProperties().get(GraphPropertiesDictionary.NAME.getProperty()), capabilityUid)).collect(Collectors.toList()); + properties.stream().forEach(p -> propertiesOfCapabilityType.remove(p.getName())); + properties.addAll(propertiesOfCapabilityType.values()); + result = Either.left(properties); + } + return result; + } + + protected Either getCapabilityTypeOfCapability(String uniqueId) { + + Either, TitanOperationStatus> capabilityTypeRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), uniqueId, GraphEdgeLabels.TYPE_OF, NodeTypeEnum.CapabilityType, + CapabilityTypeData.class); + + if (capabilityTypeRes.isRight()) { + TitanOperationStatus status = capabilityTypeRes.right().value();// + log.debug("Cannot find capability type associated with capability {}. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedFindAssociationError("Fetch Capability type", NodeTypeEnum.CapabilityType.getName(), uniqueId, String.valueOf(status)); + return Either.right(capabilityTypeRes.right().value()); + } + + CapabilityTypeData capabilityTypeData = capabilityTypeRes.left().value().getKey(); + + return Either.left(capabilityTypeData); + + } + + @Override + public Either getCapability(String capabilityName, String resourceId) { + return getCapability(UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityName)); + } + + @Override + public Either getCapability(String capabilityName, String resourceId, boolean inTransaction) { + return getCapability(UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityName), inTransaction); + } + + @Override + public Either>, TitanOperationStatus> getAllCapabilitiesPairs(String resourceId) { + + Either>, TitanOperationStatus> capabilitiesNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.CAPABILITY, + NodeTypeEnum.Capability, CapabilityData.class); + + log.debug("After looking for all capabilities under resource {}. Status is {}", resourceId, capabilitiesNodes); + if (capabilitiesNodes.isRight()) { + TitanOperationStatus status = capabilitiesNodes.right().value(); + return Either.right(status); + } + + List> capabilities = capabilitiesNodes.left().value(); + if (capabilities == null || true == capabilities.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + return Either.left(capabilitiesNodes.left().value()); + } + + private Either addCapabilityToResource(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + log.debug("Going to add capability {} [ {} ] to resource uid {}", capabilityName, capabilityDefinition, resourceId); + + Either createCapRes = createCapability(resourceId, capabilityName, capabilityDefinition); + + log.debug("After creating capability node in graph. status is {}", createCapRes); + if (createCapRes.isRight()) { + TitanOperationStatus status = createCapRes.right().value(); + log.error("Failed to create capability data node in graph. status is {}", status); + return Either.right(status); + } + CapabilityData capabilityData = createCapRes.left().value(); + + String capabilityType = capabilityDefinition.getType(); + + log.debug("Going to associate capability {} to its capabilityType {}", capabilityName, capabilityType); + + Either associateCapabilityTypeRes = associateCapabilityToCapabilityType(capabilityData, capabilityType); + log.debug("After associating capability {} to its capabilityType {}. status is {}", capabilityName, capabilityType, associateCapabilityTypeRes); + if (associateCapabilityTypeRes.isRight()) { + TitanOperationStatus status = associateCapabilityTypeRes.right().value(); + log.error("Failed to associate capability {} to its capabilityType {} in graph. status is {} ", capabilityName, capabilityType, status); + + return Either.right(status); + } + List ciProperties = capabilityDefinition.getProperties(); + if (ciProperties != null && !ciProperties.isEmpty()) { + List properties = ciProperties.stream().map(prop -> new PropertyDefinition(prop)).collect(Collectors.toList()); + Either, TitanOperationStatus> addPropertiesRes = addPropertiesToCapability(capabilityData, capabilityType, properties); + if (addPropertiesRes.isRight()) { + TitanOperationStatus operationStatus = addPropertiesRes.right().value(); + return Either.right(operationStatus); + } + } + + Either associateResourceRes = associateResourceToCapability(resourceId, capabilityName, capabilityData); + if (associateResourceRes.isRight()) { + TitanOperationStatus status = associateResourceRes.right().value(); + log.error("Failed to associate resource " + resourceId + " to capability " + capabilityData + ". status is " + status); + return Either.right(status); + } + + return Either.left(capabilityData); + + } + + private TitanOperationStatus addCapabilityToResource(TitanVertex metadataVertex, String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + log.debug("Going to add capability {} [ {} ] to resource uid {}", capabilityName, capabilityDefinition, resourceId); + + Either createCapRes = createCapabilityVertex(resourceId, capabilityName, capabilityDefinition); + + log.debug("After creating capability node in graph. status is {}", createCapRes); + if (createCapRes.isRight()) { + TitanOperationStatus status = createCapRes.right().value(); + log.error("Failed to create capability data node in graph. status is {}", status); + return status; + } + TitanVertex capabilityVertex = createCapRes.left().value(); + + String capabilityType = capabilityDefinition.getType(); + + log.debug("Going to associate capability {} to its capabilityType {}", capabilityName, capabilityType); + + TitanOperationStatus associateCapabilityTypeRes = associateCapabilityToCapabilityType(capabilityVertex, capabilityType); + log.debug("After associating capability {} to its capabilityType {}. status is {}", capabilityName, capabilityType, associateCapabilityTypeRes); + if (!associateCapabilityTypeRes.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate capability {} to its capabilityType {} in graph. status is {} ", capabilityName, capabilityType, associateCapabilityTypeRes); + return associateCapabilityTypeRes; + } + List ciProperties = capabilityDefinition.getProperties(); + if (ciProperties != null && !ciProperties.isEmpty()) { + String capabiltyId = (String) titanGenericDao.getProperty(capabilityVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + List properties = ciProperties.stream().map(prop -> new PropertyDefinition(prop)).collect(Collectors.toList()); + TitanOperationStatus addPropertiesRes = addPropertiesToCapability(capabilityVertex, capabilityType, properties, capabiltyId); + if (!addPropertiesRes.equals(TitanOperationStatus.OK)) { + return addPropertiesRes; + } + } + + TitanOperationStatus associateResourceRes = associateResourceToCapability(resourceId, capabilityName, capabilityVertex, metadataVertex); + if (!associateResourceRes.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource{} to capability {}. status is {} ", resourceId, capabilityName, associateResourceRes); + } + + return associateResourceRes; + + } + + private Either associateCapabilityToCapabilityType(CapabilityData capabilityData, String capabilityType) { + UniqueIdData capabilityTypeIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, UniqueIdBuilder.buildCapabilityTypeUid(capabilityType)); + log.debug("Before associating {} to capability type {}.", capabilityData, capabilityType); + Either createRelResult = titanGenericDao.createRelation(capabilityData, capabilityTypeIdData, GraphEdgeLabels.TYPE_OF, null); + log.debug("After associating {} to capability type {}. status is {}", capabilityData, capabilityType, createRelResult); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate capability {} to capability type {} in graph. Status is {}",capabilityData, capabilityTypeIdData, operationStatus); + return Either.right(operationStatus); + } + return Either.left(createRelResult.left().value()); + + } + + private TitanOperationStatus associateCapabilityToCapabilityType(TitanVertex capabilityVertex, String capabilityType) { + + UniqueIdData capabilityTypeIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, UniqueIdBuilder.buildCapabilityTypeUid(capabilityType)); + + log.debug("Before associating {} to capability type {}.", capabilityVertex, capabilityType); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(capabilityVertex, capabilityTypeIdData, GraphEdgeLabels.TYPE_OF, null); + log.trace("After associating {} to capability type {}. status is {}", capabilityVertex, capabilityType, createRelResult); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate capability {} to capability type {} in graph. status is {}", capabilityVertex, capabilityTypeIdData, createRelResult); + } + return createRelResult; + } + + private Either associateResourceToCapability(String resourceId, String capabilityName, CapabilityData capabilityData) { + + UniqueIdData resourceIdData = new UniqueIdData(NodeTypeEnum.Resource, resourceId); + + log.debug("Before associating resource {} to capability {}.", resourceId, capabilityData); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + Either createRelResult = titanGenericDao.createRelation(resourceIdData, capabilityData, GraphEdgeLabels.CAPABILITY, props); + log.debug("After associating resource {} to capability {}. Status is {}", resourceId, capabilityData, createRelResult); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate resource {} to capability {} in graph. Status is {}", resourceId, capabilityData, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createRelResult.left().value()); + + } + + private TitanOperationStatus associateResourceToCapability(String resourceId, String capabilityName, TitanVertex capabilityVertex, TitanVertex resourceVertex) { + + log.debug("Before associating resource {} to capability {}.", resourceId, capabilityName); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(resourceVertex, capabilityVertex, GraphEdgeLabels.CAPABILITY, props); + log.debug("After associating resource {} to capability {}. status is {}", resourceId, capabilityName, createRelResult); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to capability {} in graph. status is {}", resourceId, capabilityName, createRelResult); + } + + return createRelResult; + + } + + /** + * + * create capability node in the graph + * + * @param resourceId + * @param capabilityName + * @param capabilityDefinition + * @return + */ + private Either createCapability(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + CapabilityData capabilityData = new CapabilityData(); + String uid = UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityName); + capabilityData.setUniqueId(uid); + Long creationTime = System.currentTimeMillis(); + capabilityData.setCreationTime(creationTime); + capabilityData.setModificationTime(creationTime); + capabilityData.setValidSourceTypes(capabilityDefinition.getValidSourceTypes()); + capabilityData.setMinOccurrences(capabilityDefinition.getMinOccurrences()); + capabilityData.setMaxOccurrences(capabilityDefinition.getMaxOccurrences()); + capabilityData.setDescription(capabilityDefinition.getDescription()); + + Either createNode = titanGenericDao.createNode(capabilityData, CapabilityData.class); + + log.debug("After creating capability node in the graph. status is {}", createNode); + + return createNode; + } + + private Either createCapabilityVertex(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + CapabilityData capabilityData = new CapabilityData(); + String uid = UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityName); + capabilityData.setUniqueId(uid); + Long creationTime = System.currentTimeMillis(); + capabilityData.setCreationTime(creationTime); + capabilityData.setModificationTime(creationTime); + capabilityData.setValidSourceTypes(capabilityDefinition.getValidSourceTypes()); + capabilityData.setMinOccurrences(capabilityDefinition.getMinOccurrences()); + capabilityData.setMaxOccurrences(capabilityDefinition.getMaxOccurrences()); + capabilityData.setDescription(capabilityDefinition.getDescription()); + + Either createNode = titanGenericDao.createNode(capabilityData); + + log.debug("After creating capability node in the graph. status is {}", createNode); + + return createNode; + } + + @Override + public Either addCapability(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + return addCapability(resourceId, capabilityName, capabilityDefinition, false); + + } + + public StorageOperationStatus deleteCapabilityFromGraph(String capabilityUid) { + + TitanOperationStatus resultStatus = null; + + Either>, TitanOperationStatus> deletePropertiesStatus = deletePropertiesOfCapability(capabilityUid); + + if (deletePropertiesStatus.isRight() && !deletePropertiesStatus.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + resultStatus = deletePropertiesStatus.right().value(); + } + if (resultStatus == null) { + log.debug("Before deleting capability from graph {}", capabilityUid); + Either deleteNodeStatus = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, CapabilityData.class); + if (deleteNodeStatus.isRight()) { + resultStatus = deleteNodeStatus.right().value(); + } + } + if (resultStatus != null) { + log.debug("failed to delete capability with id {}. status={}", capabilityUid, resultStatus); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete capability", capabilityUid, String.valueOf(resultStatus)); + return DaoStatusConverter.convertTitanStatusToStorageStatus(resultStatus); + } + return StorageOperationStatus.OK; + } + + public Either, StorageOperationStatus> deleteAllCapabilities(String resourceId, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + try { + + Either, TitanOperationStatus> deleteAllRes = deleteAllCapabilitiesOfResource(resourceId); + if (deleteAllRes.isRight()) { + TitanOperationStatus status = deleteAllRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to delete capabilities of resource {}. Status is {}", resourceId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Map value = deleteAllRes.left().value(); + result = Either.left(value); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + public Either, StorageOperationStatus> deleteAllCapabilities(String resourceId) { + + return deleteAllCapabilities(resourceId, false); + + } + + private Either, TitanOperationStatus> deleteAllCapabilitiesOfResource(String resourceId) { + TitanOperationStatus resultStatus = null; + Map capabilities = new HashMap<>(); + Set caseInsensitiveCapabilityNames = new HashSet<>(); + TitanOperationStatus capabilitisRes = getCapabilitisOfResourceOnly(resourceId, capabilities, caseInsensitiveCapabilityNames); + if (capabilitisRes != TitanOperationStatus.OK) { + return Either.right(capabilitisRes); + } + + if (capabilities.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + for (Entry entry : capabilities.entrySet()) { + CapabilityDefinition capabilityDefinition = entry.getValue(); + String capabilityUid = capabilityDefinition.getUniqueId(); + + log.debug("Before deleting properties of capability {} from graph", capabilityUid); + + Either>, TitanOperationStatus> deletePropertiesStatus = deletePropertiesOfCapability(capabilityUid); + if (deletePropertiesStatus.isRight() && !deletePropertiesStatus.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + resultStatus = deletePropertiesStatus.right().value(); + } + if (resultStatus == null) { + Either deleteNodeRes = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, CapabilityData.class); + if (deleteNodeRes.isRight()) { + resultStatus = deleteNodeRes.right().value(); + } + } + if (resultStatus != null) { + log.debug("Failed to delete capability {} of resource {}", capabilityUid, resourceId); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete capability", capabilityUid, String.valueOf(resultStatus)); + return Either.right(resultStatus); + } + } + + return Either.left(capabilities); + + } + + public Map> convertCapabilityMap(Map capabilityMap, String ownerId, String ownerName) { + + Map> typeToRequirementMap = new HashMap<>(); + capabilityMap.forEach((capabilityName, capability) -> { + capability.setName(capabilityName); + if (typeToRequirementMap.containsKey(capability.getType())) { + typeToRequirementMap.get(capability.getType()).add(capability); + } else { + List list = new ArrayList<>(); + list.add(capability); + typeToRequirementMap.put(capability.getType(), list); + } + }); + return typeToRequirementMap; + } + + public TitanOperationStatus getCapabilitySourcesList(String resourceId, List derivedFromList) { + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId); + Either, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + if (getResponse.isRight()) { + return getResponse.right().value(); + } else { + String toscaResourceName = ((ResourceMetadataDataDefinition) getResponse.left().value().get(0).getMetadataDataDefinition()).getToscaResourceName(); + derivedFromList.add(toscaResourceName); + } + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.Resource, ResourceMetadataData.class); + + while (childrenNodes.isLeft()) { + + List> pairList = childrenNodes.left().value(); + ResourceMetadataData left = pairList.get(0).left; + derivedFromList.add(((ResourceMetadataDataDefinition) left.getMetadataDataDefinition()).getToscaResourceName()); + String id = left.getMetadataDataDefinition().getUniqueId(); + childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), id, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + } + return TitanOperationStatus.OK; + } + + private Either, TitanOperationStatus> addPropertiesToCapability(CapabilityData capabilityData, String capabilityType, List properties) { + String capabilityTypeUid = UniqueIdBuilder.buildCapabilityTypeUid(capabilityType); + Either, TitanOperationStatus> allPropertiesOfCapabilityTypeRes = getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeUid); + if (allPropertiesOfCapabilityTypeRes.isRight() && !allPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus operationStatus = allPropertiesOfCapabilityTypeRes.right().value(); + log.error("Failed to retrieve properties for capability type " + capabilityType + " from graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + Map propertiesOfCapabilityType = null; + + if (allPropertiesOfCapabilityTypeRes.isLeft() && allPropertiesOfCapabilityTypeRes.left() != null && !allPropertiesOfCapabilityTypeRes.left().value().isEmpty()) { + + propertiesOfCapabilityType = allPropertiesOfCapabilityTypeRes.left().value(); + Either, TitanOperationStatus> validateAndReducePropertiesRes = validatePropertyUniqueness(propertiesOfCapabilityType, properties); + if (validateAndReducePropertiesRes.isRight()) { + TitanOperationStatus operationStatus = validateAndReducePropertiesRes.right().value(); + log.error("Failed to add properties to capability {} in graph. Status is {}", capabilityData.getUniqueId(), operationStatus); + return Either.right(operationStatus); + } + } + + Either, TitanOperationStatus> addPropertiesToCapabilityRes = propertyOperation.addPropertiesToElementType(capabilityData.getUniqueId(), NodeTypeEnum.Capability, properties); + if (addPropertiesToCapabilityRes.isRight()) { + TitanOperationStatus operationStatus = addPropertiesToCapabilityRes.right().value(); + log.error("Failed to add properties to capability {} in graph. Status is {}", capabilityData.getUniqueId(), operationStatus); + return Either.right(operationStatus); + } + return Either.left(addPropertiesToCapabilityRes.left().value()); + } + + private TitanOperationStatus addPropertiesToCapability(TitanVertex capabilityVertex, String capabilityType, List properties, String uniqueId) { + String capabilityTypeUid = UniqueIdBuilder.buildCapabilityTypeUid(capabilityType); + Either, TitanOperationStatus> allPropertiesOfCapabilityTypeRes = getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeUid); + if (allPropertiesOfCapabilityTypeRes.isRight() && !allPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus operationStatus = allPropertiesOfCapabilityTypeRes.right().value(); + log.error("Failed to retrieve properties for capability type {} from graph. status is {}", capabilityType, operationStatus); + return operationStatus; + } + Map propertiesOfCapabilityType = null; + + if (allPropertiesOfCapabilityTypeRes.isLeft() && allPropertiesOfCapabilityTypeRes.left() != null && !allPropertiesOfCapabilityTypeRes.left().value().isEmpty()) { + + propertiesOfCapabilityType = allPropertiesOfCapabilityTypeRes.left().value(); + Either, TitanOperationStatus> validateAndReducePropertiesRes = validatePropertyUniqueness(propertiesOfCapabilityType, properties); + if (validateAndReducePropertiesRes.isRight()) { + TitanOperationStatus operationStatus = validateAndReducePropertiesRes.right().value(); + log.error("Failed to add properties to capability {} in graph. status is {}", capabilityVertex, operationStatus); + return operationStatus; + } + } + + String capabiltyId = (String) titanGenericDao.getProperty(capabilityVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + TitanOperationStatus addPropertiesToCapabilityRes = propertyOperation.addPropertiesToElementType(capabilityVertex, capabiltyId, NodeTypeEnum.Capability, properties); + if (!addPropertiesToCapabilityRes.equals(TitanOperationStatus.OK)) { + log.error("Failed to add properties to capability {} in graph. status is {}", capabiltyId, addPropertiesToCapabilityRes); + } + return addPropertiesToCapabilityRes; + } + + public Either, TitanOperationStatus> validatePropertyUniqueness(Map propertiesOfCapabilityType, List properties) { + Either, TitanOperationStatus> result = Either.left(properties); + + for (PropertyDefinition property : properties) { + String propertyName = property.getName(); + String propertyType = property.getType(); + PropertyDefinition defaultProperty = null; + + if (propertiesOfCapabilityType.containsKey(propertyName)) { + defaultProperty = propertiesOfCapabilityType.get(propertyName); + if (propertyType != null && defaultProperty.getType() != null && !defaultProperty.getType().equals(propertyType)) { + log.error(" Property with name {} and different type already exists.", propertyName); + result = Either.right(TitanOperationStatus.PROPERTY_NAME_ALREADY_EXISTS); + } else { + property.setType(defaultProperty.getType()); + String innerType = defaultProperty.getSchema() == null ? null : defaultProperty.getSchema().getProperty() == null ? null : defaultProperty.getSchema().getProperty().getType(); + + if (property.getSchema() != null && property.getSchema().getProperty() != null) { + property.getSchema().getProperty().setType(innerType); + } + } + } + } + return result; + } + + public StorageOperationStatus validateUpdateCapabilityProperty(PropertyDefinition property) { + Either, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return DaoStatusConverter.convertTitanStatusToStorageStatus(allDataTypes.right().value()); + } + return propertyOperation.validateAndUpdateProperty(property, allDataTypes.left().value()); + } + + public StorageOperationStatus validateCapabilityProperties(List properties) { + StorageOperationStatus result = StorageOperationStatus.OK; + for (PropertyDefinition property : properties) { + result = validateUpdateCapabilityProperty(property); + if (!result.equals(StorageOperationStatus.OK)) + break; + } + return result; + } + + public Either>, TitanOperationStatus> deletePropertiesOfCapability(String capabilityUid) { + log.debug("Before deleting properties of capability {} from graph ", capabilityUid); + + Either>, TitanOperationStatus> deletePropertiesStatus = titanGenericDao.deleteChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, GraphEdgeLabels.PROPERTY, + NodeTypeEnum.Property, PropertyData.class); + if (deletePropertiesStatus.isRight()) { + TitanOperationStatus status = deletePropertiesStatus.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to delete properties of capability with id {}. status={}", capabilityUid, status); + } else { + log.debug("The Capability with id {} have no Properties. status={}", capabilityUid, status); + } + return Either.right(status); + } + return Either.left(deletePropertiesStatus.left().value()); + } + + @Override + public Either, StorageOperationStatus> updatePropertiesOfCapability(String uniqueId, String capabilityType, List newProperties) { + return updatePropertiesOfCapability(uniqueId, capabilityType, newProperties, false); + } + + @Override + public Either, StorageOperationStatus> updatePropertiesOfCapability(String uniqueId, String capabilityType, List newProperties, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + try { + Either capabiltyRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), uniqueId, CapabilityData.class); + if (capabiltyRes.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(capabiltyRes.right().value())); + } + CapabilityData capabilityData = capabiltyRes.left().value(); + if (result == null) { + StorageOperationStatus propertiesValidationRes = validateCapabilityProperties(newProperties); + if (!propertiesValidationRes.equals(StorageOperationStatus.OK)) { + result = Either.right(propertiesValidationRes); + } + } + if (result == null) { + Either>, TitanOperationStatus> deletePropertiesRes = deletePropertiesOfCapability(uniqueId); + if (deletePropertiesRes.isRight() && !deletePropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deletePropertiesRes.right().value())); + } + } + if (result == null) { + Either, TitanOperationStatus> addPropertiesRes = addPropertiesToCapability(capabilityData, capabilityType, newProperties); + if (addPropertiesRes.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesRes.right().value())); + } else { + result = Either.left(addPropertiesRes.left().value()); + } + } + if (result.isRight()) { + log.debug("Failed to update properties of capability {}. Status is {}", uniqueId, result); + } + return result; + } finally { + if (!inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + public Either getCapabilityRelatedToResourceInstance(String resourceInstanceId, String capabilityUid) { + TitanOperationStatus error = null; + CapabilityData capability = null; + Either>, TitanOperationStatus> getCapabilitiesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class); + if (getCapabilitiesRes.isRight()) { + error = getCapabilitiesRes.right().value(); + log.debug("Failed to retrieve capabilities for resource instance {}. Status is {}", resourceInstanceId, error); + } else { + List> capabilityPairsList = getCapabilitiesRes.left().value(); + List capabilityPair = capabilityPairsList.stream().filter(pair -> pair.getLeft().getUniqueId().equals(capabilityUid)).map(pair -> pair.getLeft()).collect(Collectors.toList()); + if (capabilityPair.isEmpty()) { + error = TitanOperationStatus.NOT_FOUND; + log.debug("Failed to retrieve capability {} for resource instance {}. Status is {}", capabilityUid, resourceInstanceId, error); + } else { + capability = capabilityPair.get(0); + } + } + if (error == null) { + return Either.left(capability); + } + return Either.right(error); + } + + public Either, TitanOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType) { + Map allProperies = new HashMap<>(); + return getCapabilityTypePropertiesFromDerivedFromRecursively(firstParentType, allProperies); + } + + private Either, TitanOperationStatus> getCapabilityTypePropertiesFromDerivedFromRecursively(String nextParentType, Map allProperies) { + TitanOperationStatus error; + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), nextParentType, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + error = childrenNodes.right().value(); + log.debug("Couldn't fetch derived from node for capability type {}, error: {}", nextParentType, error); + return Either.right(error); + } else { + log.debug("Derived from node is not found for type {} - this is OK for root capability."); + return Either.left(allProperies); + } + } else { + + Either, TitanOperationStatus> allPropertiesOfCapabilityTypeRes = propertyOperation.findPropertiesOfNode(NodeTypeEnum.CapabilityType, nextParentType); + if (allPropertiesOfCapabilityTypeRes.isRight() && !allPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = allPropertiesOfCapabilityTypeRes.right().value(); + log.error("Failed to retrieve properties for capability type {} from graph. Status is {}", nextParentType, error); + return Either.right(error); + } else if (allPropertiesOfCapabilityTypeRes.isLeft()) { + if (allProperies.isEmpty()) { + allProperies.putAll(allPropertiesOfCapabilityTypeRes.left().value()); + } else { + allProperies.putAll(allPropertiesOfCapabilityTypeRes.left().value().entrySet().stream().filter(e -> !allProperies.containsKey(e.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue))); + } + } + return getCapabilityTypePropertiesFromDerivedFromRecursively(childrenNodes.left().value().get(0).getLeft().getUniqueId(), allProperies); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java new file mode 100644 index 0000000000..985399cb65 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.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.be.model.operations.impl; + +import java.util.Collection; +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.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.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.CapabilityTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +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("capability-type-operation") +public class CapabilityTypeOperation extends AbstractOperation implements ICapabilityTypeOperation { + @Autowired + private PropertyOperation propertyOperation; + @Autowired + private CapabilityOperation capabilityOperation; + + public CapabilityTypeOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(CapabilityTypeOperation.class.getName()); + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either addCapabilityType( + CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction) { + + Either result = null; + + try { + Either validationRes = validateUpdateProperties( + capabilityTypeDefinition); + if (validationRes.isRight()) { + log.error("One or all properties of capability type {} not valid. status is {}", + capabilityTypeDefinition, validationRes.right().value().name()); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(validationRes.right().value())); + return result; + } + Either eitherStatus = addCapabilityTypeToGraph( + capabilityTypeDefinition); + + if (eitherStatus.isRight()) { + log.error("Failed to add capability {} to Graph. status is {}", capabilityTypeDefinition, + eitherStatus.right().value().name()); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + CapabilityTypeData capabilityTypeData = eitherStatus.left().value(); + + CapabilityTypeDefinition capabilityTypeDefResult = convertCTDataToCTDefinition(capabilityTypeData); + log.debug("The returned CapabilityTypeDefinition is {}", capabilityTypeDefResult); + result = Either.left(capabilityTypeDefResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private Either validateUpdateProperties( + CapabilityTypeDefinition capabilityTypeDefinition) { + TitanOperationStatus error = null; + if (capabilityTypeDefinition.getProperties() != null && !capabilityTypeDefinition.getProperties().isEmpty() + && capabilityTypeDefinition.getDerivedFrom() != null) { + Either, TitanOperationStatus> allPropertiesRes = capabilityOperation + .getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeDefinition.getDerivedFrom()); + if (allPropertiesRes.isRight() + && !allPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = allPropertiesRes.right().value(); + log.debug("Couldn't fetch derived from property nodes for capability type {}, error: {}", + capabilityTypeDefinition.getType(), error); + } + if (error == null && !allPropertiesRes.left().value().isEmpty()) { + Map derivedFromProperties = allPropertiesRes.left().value(); + capabilityTypeDefinition.getProperties().entrySet().stream() + .filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null) + .forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType())); + + Either, TitanOperationStatus> validatePropertiesRes = capabilityOperation + .validatePropertyUniqueness(allPropertiesRes.left().value(), capabilityTypeDefinition + .getProperties().values().stream().collect(Collectors.toList())); + if (validatePropertiesRes.isRight()) { + error = validatePropertiesRes.right().value(); + } + } + } + if (error == null) { + return Either.left(capabilityTypeDefinition); + } + return Either.right(error); + } + + /** + * + * convert between graph Node object to Java object + * + * @param capabilityTypeData + * @return + */ + protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) { + log.debug("The object returned after create capability is {}", capabilityTypeData); + + CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition( + capabilityTypeData.getCapabilityTypeDataDefinition()); + + return capabilityTypeDefResult; + } + + /** + * + * Add capability type to graph. + * + * 1. Add capability type node + * + * 2. Add edge between the former node to its parent(if exists) + * + * 3. Add property node and associate it to the node created at #1. (per + * property & if exists) + * + * @param capabilityTypeDefinition + * @return + */ + private Either addCapabilityTypeToGraph( + CapabilityTypeDefinition capabilityTypeDefinition) { + + log.debug("Got capability type {}", capabilityTypeDefinition); + + String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType()); + // capabilityTypeDefinition.setUniqueId(ctUniqueId); + + CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId); + + log.debug("Before adding capability type to graph. capabilityTypeData = {}", capabilityTypeData); + Either createCTResult = titanGenericDao.createNode(capabilityTypeData, + CapabilityTypeData.class); + log.debug("After adding capability type to graph. status is = {}", createCTResult); + + if (createCTResult.isRight()) { + TitanOperationStatus operationStatus = createCTResult.right().value(); + log.error("Failed to capability type " + capabilityTypeDefinition.getType() + " to graph. status is " + + operationStatus); + return Either.right(operationStatus); + } + + CapabilityTypeData resultCTD = createCTResult.left().value(); + Map propertiesMap = capabilityTypeDefinition.getProperties(); + Collection properties = propertiesMap != null ? propertiesMap.values() : null; + Either, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation + .addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.CapabilityType, propertiesMap); + if (addPropertiesToCapablityType.isRight()) { + log.error( + "Failed add properties " + propertiesMap + " to capability " + capabilityTypeDefinition.getType()); + return Either.right(addPropertiesToCapablityType.right().value()); + } + + String derivedFrom = capabilityTypeDefinition.getDerivedFrom(); + if (derivedFrom != null) { + log.debug( + "Before creating relation between capability type " + ctUniqueId + " to its parent " + derivedFrom); + UniqueIdData from = new UniqueIdData(NodeTypeEnum.CapabilityType, ctUniqueId); + UniqueIdData to = new UniqueIdData(NodeTypeEnum.CapabilityType, derivedFrom); + Either createRelation = titanGenericDao.createRelation(from, to, + GraphEdgeLabels.DERIVED_FROM, null); + log.debug("After create relation between capability type {} to its parent {}. Status is {}", ctUniqueId, derivedFrom, createRelation); + if (createRelation.isRight()) { + return Either.right(createRelation.right().value()); + } + } + + return Either.left(createCTResult.left().value()); + + } + + private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, + String ctUniqueId) { + + CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition); + + capabilityTypeData.getCapabilityTypeDataDefinition().setUniqueId(ctUniqueId); + Long creationDate = capabilityTypeData.getCapabilityTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + capabilityTypeData.getCapabilityTypeDataDefinition().setCreationTime(creationDate); + capabilityTypeData.getCapabilityTypeDataDefinition().setModificationTime(creationDate); + return capabilityTypeData; + } + + @Override + public Either getCapabilityType(String uniqueId, + boolean inTransaction) { + + Either result = null; + try { + + Either ctResult = this.getCapabilityTypeByUid(uniqueId); + + if (ctResult.isRight()) { + TitanOperationStatus status = ctResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to retrieve information on capability type {}. Status is {}", uniqueId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value())); + return result; + } + + result = Either.left(ctResult.left().value()); + + return result; + } finally { + if (false == inTransaction) { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + /** + * Build Capability type object from graph by unique id + * + * @param uniqueId + * @return + */ + public Either getCapabilityTypeByUid(String uniqueId) { + + Either result = null; + + Either capabilityTypesRes = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class); + + if (capabilityTypesRes.isRight()) { + TitanOperationStatus status = capabilityTypesRes.right().value(); + log.debug("Capability type {} cannot be found in graph. Status is {}", uniqueId, status); + return Either.right(status); + } + + CapabilityTypeData ctData = capabilityTypesRes.left().value(); + CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition( + ctData.getCapabilityTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = fillProperties(uniqueId, capabilityTypeDefinition); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of capability type " + uniqueId); + return Either.right(propertiesStatus); + } + + Either, TitanOperationStatus> parentNode = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + log.debug("After retrieving DERIVED_FROM node of {}. Status is {}", uniqueId, parentNode); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the parent capability of capability type {}. Status is {}", uniqueId, titanOperationStatus); + result = Either.right(titanOperationStatus); + return result; + } + } else { + // derived from node was found + ImmutablePair immutablePair = parentNode.left().value(); + CapabilityTypeData parentCT = immutablePair.getKey(); + capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType()); + } + result = Either.left(capabilityTypeDefinition); + + return result; + } + + private TitanOperationStatus fillProperties(String uniqueId, CapabilityTypeDefinition capabilityTypeDefinition) { + + Either, TitanOperationStatus> findPropertiesOfNode = propertyOperation + .findPropertiesOfNode(NodeTypeEnum.CapabilityType, uniqueId); + if (findPropertiesOfNode.isRight()) { + TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value(); + log.debug("After looking for properties of vertex {}. Status is {}", uniqueId, titanOperationStatus); + if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) { + return TitanOperationStatus.OK; + } else { + return titanOperationStatus; + } + } else { + Map properties = findPropertiesOfNode.left().value(); + capabilityTypeDefinition.setProperties(properties); + return TitanOperationStatus.OK; + } + } + + public Either isCapabilityTypeDerivedFrom(String childCandidateType, + String parentCandidateType) { + Map propertiesToMatch = new HashMap(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childCandidateType); + Either, TitanOperationStatus> getResponse = titanGenericDao + .getByCriteria(NodeTypeEnum.CapabilityType, propertiesToMatch, CapabilityTypeData.class); + if (getResponse.isRight()) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch capability type {}, error: {}", childCandidateType, titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } + String childUniqueId = getResponse.left().value().get(0).getUniqueId(); + Set travelledTypes = new HashSet<>(); + do { + travelledTypes.add(childUniqueId); + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childUniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch derived from node for capability type {}, error: {}", childCandidateType, + titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } else { + log.debug("Derived from node is not found for type {} - this is OK for root capability."); + return Either.left(false); + } + } + String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId(); + if (derivedFromUniqueId.equals(parentCandidateType)) { + log.debug("Verified that capability type {} derives from capability type {}", childCandidateType, + parentCandidateType); + return Either.left(true); + } + childUniqueId = derivedFromUniqueId; + } while (!travelledTypes.contains(childUniqueId)); + // this stop condition should never be used, if we use it, we have an + // illegal cycle in graph - "derived from" hierarchy cannot be cycled. + // It's here just to avoid infinite loop in case we have such cycle. + log.error("Detected a cycle of \"derived from\" edges starting at capability type node {}", childUniqueId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + /** + * FOR TEST ONLY + * + * @param propertyOperation + */ + public void setPropertyOperation(PropertyOperation propertyOperation) { + this.propertyOperation = propertyOperation; + } + + @Override + public Either addCapabilityType( + CapabilityTypeDefinition capabilityTypeDefinition) { + + return addCapabilityType(capabilityTypeDefinition, false); + } + + @Override + public Either getCapabilityType(String uniqueId) { + return getCapabilityType(uniqueId, false); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java new file mode 100644 index 0000000000..cb85888780 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java @@ -0,0 +1,5852 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +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.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +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.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +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.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; +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.datatypes.enums.OriginTypeEnum; +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.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.DataTypeDefinition; +import org.openecomp.sdc.be.model.GetInputValueInfo; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement; +import org.openecomp.sdc.be.model.InputDefinition; +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.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.operations.api.IAttributeOperation; +import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.AttributeValueData; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.InputValueData; +import org.openecomp.sdc.be.resources.data.InputsData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.RelationshipInstData; +import org.openecomp.sdc.be.resources.data.RelationshipTypeData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +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.Wrapper; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; +import com.thinkaurelius.titan.core.TitanVertexQuery; + +import fj.data.Either; + +@org.springframework.stereotype.Component("component-instance-operation") +public class ComponentInstanceOperation extends AbstractOperation implements IComponentInstanceOperation { + + public ComponentInstanceOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(ComponentInstanceOperation.class.getName()); + + @Autowired + private ResourceOperation resourceOperation; + + @Autowired + private ServiceOperation serviceOperation; + + @Autowired + CapabilityOperation capabilityOperation; + + @Autowired + private CapabilityInstanceOperation capabilityInstanceOperation; + + @Autowired + private CapabilityTypeOperation capabilityTypeOperation; + + @Autowired + private RequirementOperation requirementOperation; + + @Autowired + private ArtifactOperation artifactOperation; + + @Autowired + TitanGenericDao titanGenericDao; + + @Autowired + PropertyOperation propertyOperation; + + @Autowired + InputsOperation inputOperation; + + @Autowired + private IAttributeOperation attributeOperation; + + @Autowired + private ApplicationDataTypeCache dataTypeCache; + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either createComponentInstance(String parentComponentId, NodeTypeEnum nodeType, String instanceNumber, ComponentInstance componentInstance, NodeTypeEnum compInstNodeType, boolean inTransaction) { + + return createComponentInstance(parentComponentId, nodeType, instanceNumber, true, componentInstance, compInstNodeType, false, inTransaction); + + } + + private Either createComponentInstance(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, boolean isCreateLocgicalName, ComponentInstance componentInstance, + NodeTypeEnum compInstNodeType, boolean allowDeleted, boolean inTransaction) { + Either result = null; + + try { + + Either addRes = addComponentInstanceToContainerComponent(containerComponentId, containerNodeType, instanceNumber, isCreateLocgicalName, componentInstance, compInstNodeType, allowDeleted); + if (addRes.isRight()) { + TitanOperationStatus status = addRes.right().value(); + log.error("Failed to add resource instance {} to service {}. Status is {}", componentInstance, containerComponentId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ComponentInstance value = addRes.left().value(); + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + } + + private Either createComponentInstance(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, boolean isCreateLocgicalName, ComponentInstance componentInstance, + NodeTypeEnum compInstNodeType, boolean allowDeleted, boolean inTransaction, TitanVertex metadataVertex) { + Either result = null; + + try { + + Either addRes = addComponentInstanceToContainerComponent(containerComponentId, containerNodeType, instanceNumber, isCreateLocgicalName, componentInstance, compInstNodeType, allowDeleted, metadataVertex); + if (addRes.isRight()) { + TitanOperationStatus status = addRes.right().value(); + log.error("Failed to add resource instance {} to service {}. status is {}", componentInstance, containerComponentId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + TitanVertex value = addRes.left().value(); + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + } + + @Override + public Either createComponentInstance(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, ComponentInstance componentInstance, NodeTypeEnum instNodeType) { + + return createComponentInstance(containerComponentId, containerNodeType, instanceNumber, componentInstance, instNodeType, false); + + } + + @Override + public Either deleteComponentInstance(NodeTypeEnum containerNodeType, String containerComponentId, String resourceInstUid, boolean inTransaction) { + + Either result = null; + + try { + + Either deleteRes = removeComponentInstanceFromComponent(containerNodeType, containerComponentId, resourceInstUid); + + if (deleteRes.isRight()) { + TitanOperationStatus status = deleteRes.right().value(); + log.error("Failed to remove resource instance {} from component {}. Status is {}", resourceInstUid, containerComponentId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ComponentInstance value = deleteRes.left().value(); + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + + } + + @Override + public Either deleteComponentInstance(NodeTypeEnum containerNodeType, String containerComponentId, String resourceInstUid) { + + return deleteComponentInstance(containerNodeType, containerComponentId, resourceInstUid, false); + } + + private void commitOrRollback(Either result) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + + @Override + public Either validateParent(String parentId, String uniqId, boolean inTransaction) { + + Either result = null; + Either updateRes = validateParentonGraph(parentId, uniqId, inTransaction); + + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + log.error("Failed to find resource instance name {}. Status is {}", uniqId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Boolean value = updateRes.left().value(); + + result = Either.left(value); + + return result; + + } + + public Either validateParentonGraph(String parentId, String uniqId, boolean inTransaction) { + + Either graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.debug("Failed to retrieve graph. status is {}", graphRes); + return Either.right(graphRes.right().value()); + } + TitanGraph titanGraph = graphRes.left().value(); + try { + Iterable vertices = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), uniqId).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + TitanVertex vertex = vertices.iterator().next(); + + TitanVertexQuery query = vertex.query(); + query = query.labels(GraphEdgeLabels.RESOURCE_INST.getProperty()).direction(Direction.IN); + Iterable verts = query.vertices(); + if (verts == null) { + log.debug("No edges in graph for criteria"); + return Either.right(TitanOperationStatus.INVALID_ID); + } + Iterator vIter = verts.iterator(); + if (vIter.hasNext()) { + Vertex vert = vIter.next(); + // vert.getProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String resInstName = vert.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (resInstName.equals(parentId)) + return Either.left(Boolean.TRUE); + } + return Either.left(Boolean.FALSE); + } finally { + if (false == inTransaction) { + titanGraph.tx().commit(); + } + } + } + + public Either addComponentInstanceToContainerComponent(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, boolean isCreateLogicaName, ComponentInstance componentInstance, + NodeTypeEnum compInstNodeType, boolean allowDeleted) { + log.debug("Going to create component instance {} in component {}", componentInstance, containerComponentId); + + Either metadataVertex = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), containerComponentId); + if (metadataVertex.isRight()) { + TitanOperationStatus status = metadataVertex.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + Either addComponentInstanceToContainerComponent = addComponentInstanceToContainerComponent(containerComponentId, containerNodeType, instanceNumber, isCreateLogicaName, componentInstance, compInstNodeType, + allowDeleted, metadataVertex.left().value()); + + if (addComponentInstanceToContainerComponent.isRight()) { + TitanOperationStatus status = addComponentInstanceToContainerComponent.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + TitanVertex ciVertex = addComponentInstanceToContainerComponent.left().value(); + Map properties = titanGenericDao.getProperties(ciVertex); + ComponentInstanceData createdComponentInstance = GraphElementFactory.createElement(NodeTypeEnum.ResourceInstance.getName(), GraphElementTypeEnum.Node, properties, ComponentInstanceData.class); + + ComponentInstance createdResourceInstance = new ComponentInstance(createdComponentInstance.getComponentInstDataDefinition()); + + return Either.left(createdResourceInstance); + + } + + /** + * + * @param containerComponentId + * @param containerNodeType + * @param instanceNumber + * @param isCreateLogicaName + * @param componentInstance + * @param compInstNodeType + * @param allowDeleted + * @param metadataVertex + * @return + */ + public Either addComponentInstanceToContainerComponent(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, boolean isCreateLogicaName, ComponentInstance componentInstance, + NodeTypeEnum compInstNodeType, boolean allowDeleted, TitanVertex metadataVertex) { + TitanOperationStatus status; + log.debug("Going to create component instance {} in component {}", componentInstance, containerComponentId); + String instOriginComponentId = componentInstance.getComponentUid(); + String logicalName = componentInstance.getName(); + if (isCreateLogicaName) + logicalName = createComponentInstLogicalName(instanceNumber, componentInstance.getName()); + + ComponentInstanceData componentInstanceData = buildComponentInstanceData(componentInstance, containerComponentId, logicalName); + Either originVertexEither = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), instOriginComponentId); + if (originVertexEither.isRight()) { + log.debug("Failed to fetch vertex of origin resource for id {} error {}", instOriginComponentId, originVertexEither.right().value()); + return Either.right(originVertexEither.right().value()); + } + TitanVertex originVertex = originVertexEither.left().value(); + + Boolean isDeleted = (Boolean) titanGenericDao.getProperty(metadataVertex, GraphPropertiesDictionary.IS_DELETED.getProperty()); + + if (!allowDeleted && (isDeleted != null) && (isDeleted == true)) { + log.debug("Component {} is already deleted. Cannot add component instance", instOriginComponentId); + return Either.right(TitanOperationStatus.INVALID_ID); + } + String originType = (String) titanGenericDao.getProperty(originVertex, GraphPropertiesDictionary.LABEL.getProperty()); + String resourceType = (String) titanGenericDao.getProperty(originVertex, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty()); + detectOriginType(originType, componentInstanceData, resourceType); + + log.trace("Before adding component instance to graph. componentInstanceData = {}", componentInstanceData); + + Either createCIResult = titanGenericDao.createNode(componentInstanceData); + + log.debug("After adding component instance to graph. status is = {}", createCIResult); + + if (createCIResult.isRight()) { + status = createCIResult.right().value(); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to create component instance node in graph. status is {}", status); + return Either.right(status); + } + TitanVertex createdComponentInstanceVertex = createCIResult.left().value(); + TitanOperationStatus associateContainerRes = associateContainerCompToComponentInstance(metadataVertex, createdComponentInstanceVertex, logicalName); + + String componentInstanceUniqueId = componentInstanceData.getUniqueId(); + if (!associateContainerRes.equals(TitanOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to associate container component {} to component instance {}. Status is {}", containerComponentId, componentInstanceUniqueId, associateContainerRes); + return Either.right(associateContainerRes); + } + String originId = (String) titanGenericDao.getProperty(createdComponentInstanceVertex, GraphPropertiesDictionary.TYPE.getProperty()); + + TitanOperationStatus associateToInstOriginComponent = associateToInstOriginComponent(createdComponentInstanceVertex, originVertex, originId); + if (!associateToInstOriginComponent.equals(TitanOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to associate component instance {} to its origin component {}. Status is {}", componentInstanceUniqueId, componentInstanceData.getComponentInstDataDefinition().getComponentUid(), associateToInstOriginComponent); + return Either.right(associateToInstOriginComponent); + } + + TitanOperationStatus associateCompInstToRequirements = associateCompInstToRequirements(createdComponentInstanceVertex, containerNodeType, compInstNodeType, originId); + if (!associateCompInstToRequirements.equals(TitanOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to associate component instance {} to its origin requirements. Status is {}", componentInstanceUniqueId, associateCompInstToRequirements); + return Either.right(associateCompInstToRequirements); + } + TitanOperationStatus associateCompInstToCapabilities = associateCompInstToCapabilities(createdComponentInstanceVertex, containerNodeType, compInstNodeType, originId); + if (!associateCompInstToCapabilities.equals(TitanOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to associate component instance {} to its origin capabilities. Status is {}", componentInstanceUniqueId, associateCompInstToCapabilities); + return Either.right(associateCompInstToCapabilities); + } + // Capability instance with property values implementation + Either>, TitanOperationStatus> cloneCapabilityInstancesRes = null; + Either, TitanOperationStatus> associateComponentInstanceToCapabilityInstancesRes; + status = null; + if (!isCreateLogicaName) { + // in case of cloning of component instance + log.debug("Before cloning of capability instances of component instance {}.", componentInstance.getUniqueId()); + cloneCapabilityInstancesRes = cloneCapabilityInstancesOfResourceInstance(createdComponentInstanceVertex, componentInstance); + if (cloneCapabilityInstancesRes.isRight() && !cloneCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + status = cloneCapabilityInstancesRes.right().value(); + log.debug("Failed to clone capability instances of component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } + log.trace("After cloning of capability instances of component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } else if (containerNodeType.equals(NodeTypeEnum.Resource) && componentInstance.getCapabilities() != null && !componentInstance.getCapabilities().isEmpty()) { + // in case of creation from scar + TitanOperationStatus addPropertiesRes = createCapabilityInstancesWithPropertyValues(createdComponentInstanceVertex, componentInstanceUniqueId, componentInstance.getCapabilities(), true); + if (!addPropertiesRes.equals(TitanOperationStatus.OK)) { + status = addPropertiesRes; + log.debug("Failed to create capability instances with property values for component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } + } + if (status == null && containerNodeType.equals(NodeTypeEnum.Service)) { + Map properties = titanGenericDao.getProperties(createdComponentInstanceVertex); + ComponentInstanceData createdComponentInstance = GraphElementFactory.createElement(NodeTypeEnum.ResourceInstance.getName(), GraphElementTypeEnum.Node, properties, ComponentInstanceData.class); + if (cloneCapabilityInstancesRes == null || cloneCapabilityInstancesRes.isRight()) { + // in case of creating of service + log.trace("Before associating component instance {} to capability instances .", componentInstance.getUniqueId()); + associateComponentInstanceToCapabilityInstancesRes = associateComponentInstanceToCapabilityInstancesOfResourceInstance(componentInstance); + if (associateComponentInstanceToCapabilityInstancesRes.isRight() && !associateComponentInstanceToCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + status = associateComponentInstanceToCapabilityInstancesRes.right().value(); + log.debug("Failed to associate capability instances to component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } + log.trace("After associating component instance {} to capability instances . Status is {}", componentInstance.getUniqueId(), status); + } else { + // in case of cloning of service + log.trace("Before associating created component instance {} to cloned capability instances.", componentInstanceUniqueId); + TitanOperationStatus associationStatus = associateCreatedComponentInstanceToClonedCapabilityInstances(createdComponentInstanceVertex, componentInstanceUniqueId, cloneCapabilityInstancesRes.left().value()); + if (!associationStatus.equals(TitanOperationStatus.OK) && !associationStatus.equals(TitanOperationStatus.NOT_FOUND)) { + status = associationStatus; + log.debug("Failed to associate capability instances to component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } + log.trace("After associating created component instance {} to cloned capability instances. Status is {}", componentInstanceUniqueId, status); + } + } + if (status == null) { + // ComponentInstance createdResourceInstance = new + // ComponentInstance(createdComponentInstance.getComponentInstDataDefinition()); + // + // String icon = (String) titanGenericDao.getProperty(originVertex, + // GraphPropertiesDictionary.ICON.getProperty()); + // createdResourceInstance.setIcon(icon); + return Either.left(createdComponentInstanceVertex); + } + return Either.right(status); + } + + private Either>, TitanOperationStatus> createCapabilityInstancesWithPropertyValues(String resourceInstanceId, Map> capabilities, + boolean isNewlyCreatedResourceInstance) { + TitanOperationStatus error; + Map> result = new HashMap<>(); + for (Entry> capailityEntry : capabilities.entrySet()) { + CapabilityDefinition capability = capailityEntry.getValue().get(0); + if (capability.getProperties() != null && !capability.getProperties().isEmpty()) { + Either>, TitanOperationStatus> addPropertiesRes = addCapabilityPropertyValuesToResourceInstance(resourceInstanceId, capability, isNewlyCreatedResourceInstance); + if (addPropertiesRes.isRight()) { + error = addPropertiesRes.right().value(); + log.debug("Failed to add property values to capabilities of component instance {}. Status is {}", resourceInstanceId, error); + return Either.right(error); + } else { + result.putAll(addPropertiesRes.left().value()); + } + } + } + return Either.left(result); + } + + private TitanOperationStatus createCapabilityInstancesWithPropertyValues(TitanVertex resourceInstanceVertex, String resourceInstanceId, Map> capabilities, boolean isNewlyCreatedResourceInstance) { + TitanOperationStatus result = TitanOperationStatus.OK; + + for (Entry> capailityEntry : capabilities.entrySet()) { + CapabilityDefinition capability = capailityEntry.getValue().get(0); + if (capability.getProperties() != null && !capability.getProperties().isEmpty()) { + TitanOperationStatus addPropertiesRes = addCapabilityPropertyValuesToResourceInstance(resourceInstanceVertex, resourceInstanceId, capability, isNewlyCreatedResourceInstance); + if (!addPropertiesRes.equals(TitanOperationStatus.OK)) { + result = addPropertiesRes; + log.debug("Failed to add property values to capabilities of component instance {}. Status is {}", resourceInstanceId, result); + return result; + } + } + } + return result; + } + + private Either, TitanOperationStatus> associateCreatedComponentInstanceToClonedCapabilityInstances(String newComponentResourceId, List> capabilityInstances) { + TitanOperationStatus error = null; + List relationsToCapabilityInstances = new ArrayList<>(); + UniqueIdData componentInstanceIdData = new UniqueIdData(NodeTypeEnum.ResourceInstance, newComponentResourceId); + for (ImmutablePair capInstPair : capabilityInstances) { + Either associateComponentInstanceToCapabilityinstanceRes = titanGenericDao.createRelation(componentInstanceIdData, capInstPair.getLeft(), GraphEdgeLabels.CAPABILITY_INST, + capInstPair.getRight().getProperties()); + if (associateComponentInstanceToCapabilityinstanceRes.isRight()) { + error = associateComponentInstanceToCapabilityinstanceRes.right().value(); + log.debug("Failed to associate capability instance {} to resource instance {}. Status is {}.", capInstPair.getLeft().getUniqueId(), newComponentResourceId, error); + break; + } else { + relationsToCapabilityInstances.add(associateComponentInstanceToCapabilityinstanceRes.left().value()); + } + } + if (error == null) { + return Either.left(relationsToCapabilityInstances); + } + return Either.right(error); + } + + private TitanOperationStatus associateCreatedComponentInstanceToClonedCapabilityInstances(TitanVertex riVertex, String newComponentResourceId, List> capabilityInstances) { + TitanOperationStatus error = null; + for (ImmutablePair capInstPair : capabilityInstances) { + TitanOperationStatus associateComponentInstanceToCapabilityinstanceRes = titanGenericDao.createEdge(riVertex, capInstPair.getLeft(), GraphEdgeLabels.CAPABILITY_INST, capInstPair.getRight().getProperties()); + if (!associateComponentInstanceToCapabilityinstanceRes.equals(TitanOperationStatus.OK)) { + error = associateComponentInstanceToCapabilityinstanceRes; + log.debug("Failed to associate capability instance {} to resource instance {} status is {} .", capInstPair.getLeft(), newComponentResourceId, error); + break; + } + } + if (error == null) { + return TitanOperationStatus.OK; + } + return error; + } + + private Either, TitanOperationStatus> associateComponentInstanceToCapabilityInstancesOfResourceInstance(ComponentInstance componentInstance) { + TitanOperationStatus error = null; + String resourceId = componentInstance.getComponentUid(); + String componentResourceId = componentInstance.getUniqueId(); + UniqueIdData componentInstanceIdData = new UniqueIdData(NodeTypeEnum.ResourceInstance, componentResourceId); + List> resourceInstancesPair; + List> allCapabilityInstancesList = new ArrayList<>(); + List relationsToCapabilityInstances = new ArrayList<>(); + Either>, TitanOperationStatus> getAllResourceInstanceRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.RESOURCE_INST, NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + if (getAllResourceInstanceRes.isRight() && !getAllResourceInstanceRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getAllResourceInstanceRes.right().value(); + log.debug("Failed to retrieve resource instances from resource {}. Status is {}.", resourceId, error); + } + if (getAllResourceInstanceRes.isLeft()) { + resourceInstancesPair = getAllResourceInstanceRes.left().value(); + ComponentInstanceData ri; + for (ImmutablePair riPair : resourceInstancesPair) { + ri = riPair.getLeft(); + Either>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), ri.getUniqueId(), + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + if (getCapabilityInstancesRes.isRight() && !getCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability instances of resource instance {}. Status is {}", ri.getUniqueId(), error); + break; + } + if (getCapabilityInstancesRes.isLeft()) { + allCapabilityInstancesList.addAll(getCapabilityInstancesRes.left().value()); + } + } + } + if (error == null && !allCapabilityInstancesList.isEmpty()) { + for (ImmutablePair capInstPair : allCapabilityInstancesList) { + Either associateComponentInstanceToCapabilityinstanceRes = titanGenericDao.createRelation(componentInstanceIdData, capInstPair.getLeft(), GraphEdgeLabels.CAPABILITY_INST, + capInstPair.getRight().getProperties()); + if (associateComponentInstanceToCapabilityinstanceRes.isRight()) { + error = associateComponentInstanceToCapabilityinstanceRes.right().value(); + log.debug("Failed to associate capability instance {} to resource instance {}. Status is {}", capInstPair.getLeft().getUniqueId(), componentResourceId, error); + break; + } else { + relationsToCapabilityInstances.add(associateComponentInstanceToCapabilityinstanceRes.left().value()); + } + } + } + if (error == null) { + return Either.left(relationsToCapabilityInstances); + } + return Either.right(error); + } + + private void detectOriginType(String label, ComponentInstanceData componentInstanceData, String resourceTypeStr) { + switch (NodeTypeEnum.getByName(label)) { + case Service: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.SERVICE); + break; + case Product: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.PRODUCT); + break; + case Resource: + ResourceTypeEnum resourceType = ResourceTypeEnum.valueOf(resourceTypeStr); + switch (resourceType) { + case VF: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.VF); + break; + case VFC: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.VFC); + break; + case CP: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.CP); + break; + case VL: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.VL); + break; + } + break; + default: + break; + } + } + + private Either associateToInstOriginComponent(ComponentInstanceData componentInstanceData, NodeTypeEnum compInstNodeType) { + + UniqueIdData resourceIdData = new UniqueIdData(compInstNodeType, componentInstanceData.getComponentInstDataDefinition().getComponentUid()); + + Either createRelation = titanGenericDao.createRelation(componentInstanceData, resourceIdData, GraphEdgeLabels.INSTANCE_OF, null); + + log.debug("After associating resource instance {} to resource {}. Status is {}", + componentInstanceData.getUniqueId(), + componentInstanceData.getComponentInstDataDefinition().getUniqueId(), + createRelation); + + return createRelation; + } + + private TitanOperationStatus associateToInstOriginComponent(TitanVertex componentInstanceVertex, TitanVertex originVertex, String originId) { + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, originVertex, GraphEdgeLabels.INSTANCE_OF, null); + + log.debug("After associating resource instance {} to resource {}. status is {}", componentInstanceVertex, originId, createRelation); + + return createRelation; + } + + private Either, TitanOperationStatus> associateCompInstToRequirements(ComponentInstanceData componentInstanceData, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType) { + log.trace("Starting to copy origin component requirements to its component instance"); + String compInstOriginId = componentInstanceData.getComponentInstDataDefinition().getComponentUid(); + List graphRelations = new ArrayList<>(); + + // case of VFC / CP / VL + if (compInstNodeType.equals(NodeTypeEnum.Resource)) { + createRequirementRelationsFromAtomicResource(componentInstanceData, compInstOriginId, graphRelations); + + } + // case of VF / Service / Product + createCalculatedRequirementRelationsFromComponent(componentInstanceData, containerNodeType, compInstNodeType, graphRelations, compInstOriginId); + + log.trace("Finished to copy origin component requirements to its component instance, created {} new calculated requirement relations", graphRelations.size()); + return Either.left(graphRelations); + } + + private TitanOperationStatus associateCompInstToRequirements(TitanVertex componentInstanceVertex, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, String originId) { + log.trace("Starting to copy origin component requirements to its component instance"); + TitanOperationStatus status = TitanOperationStatus.OK; + // case of VFC / CP / VL + if (compInstNodeType.equals(NodeTypeEnum.Resource)) { + status = createRequirementRelationsFromAtomicResource(componentInstanceVertex, originId); + if (!status.equals(TitanOperationStatus.OK)) { + log.debug("Failed create relation to requirement of origin {} error {}", originId, status); + return status; + } + } + // case of VF / Service / Product + status = createCalculatedRequirementRelationsFromComponent(componentInstanceVertex, containerNodeType, compInstNodeType, originId); + + log.trace("Finished to copy origin component requirements to its component instance with status {}", status); + return status; + } + + private void createRequirementRelationsFromAtomicResource(ComponentInstanceData componentInstanceData, String compInstOriginId, List graphRelations) { + Map requirements = new HashMap(); + Set caseInsensitiveReqNames = new HashSet<>(); + + TitanOperationStatus status = requirementOperation.findAllRequirementsRecursively(compInstOriginId, requirements, caseInsensitiveReqNames); + if (status != TitanOperationStatus.OK) { + log.debug("Couldn't fetch requirements of component {}, error: {}", compInstOriginId, status); + } + + log.trace("Found {} requirements for component {}, ", requirements.size(), compInstOriginId); + for (Entry reqPair : requirements.entrySet()) { + RequirementDefinition requirementDef = reqPair.getValue(); + RequirementData requirementData = new RequirementData(); + requirementData.setUniqueId(requirementDef.getUniqueId()); + + log.trace("Creating calculated requirement relation from component instance {} to requirement {}", componentInstanceData.getUniqueId(), requirementDef.getUniqueId()); + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), reqPair.getKey()); + + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), componentInstanceData.getUniqueId()); + if (requirementDef.getMinOccurrences() == null) { + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), RequirementData.MIN_OCCURRENCES); + } else { + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), requirementDef.getMinOccurrences()); + } + if (requirementDef.getMaxOccurrences() == null) { + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), RequirementData.MAX_DEFAULT_OCCURRENCES); + } else { + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), requirementDef.getMaxOccurrences()); + } + + Either createRelation = titanGenericDao.createRelation(componentInstanceData, requirementData, 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: {}", componentInstanceData.getUniqueId(), requirementDef.getUniqueId(), titanOperationStatus); + } + graphRelations.add(createRelation.left().value()); + } + } + + private TitanOperationStatus createRequirementRelationsFromAtomicResource(TitanVertex componentInstanceVertex, String compInstOriginId) { + Map requirements = new HashMap(); + Set caseInsensitiveReqNames = new HashSet<>(); + + TitanOperationStatus status = requirementOperation.findAllRequirementsRecursively(compInstOriginId, requirements, caseInsensitiveReqNames); + if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) { + log.debug("Couldn't fetch requirements of component {}, error: {}", compInstOriginId, status); + return status; + } + + String compoInstId = (String) titanGenericDao.getProperty(componentInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + log.trace("Found {} requirements for component {}, ", requirements.size(), compInstOriginId); + for (Entry reqPair : requirements.entrySet()) { + RequirementDefinition requirementDef = reqPair.getValue(); + RequirementData requirementData = new RequirementData(); + requirementData.setUniqueId(requirementDef.getUniqueId()); + + log.trace("Creating calculated requirement relation from component instance {} to requirement {}", compoInstId, requirementDef.getUniqueId()); + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), reqPair.getKey()); + + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), compoInstId); + if (requirementDef.getMinOccurrences() == null) { + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), RequirementData.MIN_OCCURRENCES); + } else { + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), requirementDef.getMinOccurrences()); + } + if (requirementDef.getMaxOccurrences() == null) { + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), RequirementData.MAX_DEFAULT_OCCURRENCES); + } else { + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), requirementDef.getMaxOccurrences()); + } + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, requirementData, GraphEdgeLabels.CALCULATED_REQUIREMENT, props); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated requirement from component instance {} to requirement {}, error: {}", compoInstId, requirementDef.getUniqueId(), createRelation); + return createRelation; + } + } + return TitanOperationStatus.OK; + } + + private Either, TitanOperationStatus> associateCompInstToCapabilities(ComponentInstanceData componentInstanceData, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType) { + + log.trace("Starting to copy origin component capabilities to its component instance"); + List graphRelations = new ArrayList<>(); + + String compInstOriginId = componentInstanceData.getComponentInstDataDefinition().getComponentUid(); + + // case of VFC / CP / VL + if (compInstNodeType.equals(NodeTypeEnum.Resource)) { + createCaculatedRelationsFromAtomicResource(componentInstanceData, graphRelations, compInstOriginId); + } + + // case of VF / Service / Product + createCalculatedCapabilityRelationsFromComponent(componentInstanceData, containerNodeType, compInstNodeType, graphRelations, compInstOriginId); + + log.trace("Finished to copy origin component capabilities to its component instance, created {} new calculated capability relations", graphRelations.size()); + return Either.left(graphRelations); + } + + private TitanOperationStatus associateCompInstToCapabilities(TitanVertex componentInstanceVertex, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, String originId) { + + log.trace("Starting to copy origin component capabilities to its component instance"); + TitanOperationStatus status = TitanOperationStatus.OK; + + // case of VFC / CP / VL + if (compInstNodeType.equals(NodeTypeEnum.Resource)) { + status = createCaculatedRelationsFromAtomicResource(componentInstanceVertex, originId); + if (!status.equals(TitanOperationStatus.OK)) { + return status; + } + } + + // case of VF / Service / Product + status = createCalculatedCapabilityRelationsFromComponent(componentInstanceVertex, containerNodeType, compInstNodeType, originId); + + return status; + } + + private void createCalculatedRequirementRelationsFromComponent(ComponentInstanceData componentInstanceData, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, List graphRelations, String compInstOriginId) { + + Either, List>, TitanOperationStatus> componentInstancesOfComponent = getComponentInstancesOfComponent(compInstOriginId, containerNodeType, compInstNodeType); + if (componentInstancesOfComponent.isLeft() && !componentInstancesOfComponent.left().value().left.isEmpty()) { + List componentInstances = componentInstancesOfComponent.left().value().left; + for (ComponentInstance componentInstance : componentInstances) { + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(containerNodeType), componentInstance.getUniqueId(), + GraphEdgeLabels.CALCULATED_REQUIREMENT, NodeTypeEnum.Requirement, RequirementData.class); + + if (childrenNodes.isLeft() && !childrenNodes.left().value().isEmpty()) { + List> list = childrenNodes.left().value(); + for (ImmutablePair calculatedReq : list) { + + GraphEdge edge = calculatedReq.right; + Map properties = edge.getProperties(); + String source = null; + String occurrences = RequirementData.MAX_DEFAULT_OCCURRENCES; + String minOccurrences = RequirementData.MIN_OCCURRENCES; + + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.SOURCE.getProperty())) { + source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty())) { + occurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty())) { + minOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + } + + String capabilityName = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + Either createRelation = createCalculatedRequirementEdge(componentInstanceData, source, capabilityName, calculatedReq.left, componentInstance, occurrences, minOccurrences); + if (createRelation.isLeft()) { + graphRelations.add(createRelation.left().value()); + } + } + } + } + } + } + + private TitanOperationStatus createCalculatedRequirementRelationsFromComponent(TitanVertex componentInstanceVertex, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, String compInstOriginId) { + + Either, List>, TitanOperationStatus> componentInstancesOfComponent = getComponentInstancesOfComponent(compInstOriginId, containerNodeType, compInstNodeType); + if (componentInstancesOfComponent.isLeft() && !componentInstancesOfComponent.left().value().left.isEmpty()) { + List componentInstances = componentInstancesOfComponent.left().value().left; + for (ComponentInstance componentInstance : componentInstances) { + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(containerNodeType), componentInstance.getUniqueId(), + GraphEdgeLabels.CALCULATED_REQUIREMENT); + + if (childrenNodes.isLeft() && !childrenNodes.left().value().isEmpty()) { + List> list = childrenNodes.left().value(); + for (ImmutablePair calculatedReq : list) { + + Edge edge = calculatedReq.right; + Map properties = titanGenericDao.getProperties(edge); + String source = null; + String occurrences = RequirementData.MAX_DEFAULT_OCCURRENCES; + String minOccurrences = RequirementData.MIN_OCCURRENCES; + + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.SOURCE.getProperty())) { + source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty())) { + occurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty())) { + minOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + } + + String capabilityName = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + TitanOperationStatus createRelation = createCalculatedRequirementEdge(componentInstanceVertex, source, capabilityName, calculatedReq.left, componentInstance, occurrences, minOccurrences); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated requirement edge, status ", createRelation); + return createRelation; + } + } + } + } + } + return TitanOperationStatus.OK; + } + + private void createCalculatedCapabilityRelationsFromComponent(ComponentInstanceData componentInstanceData, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, List graphRelations, String compInstOriginId) { + + Either, List>, TitanOperationStatus> componentInstancesOfComponent = getComponentInstancesOfComponent(compInstOriginId, containerNodeType, compInstNodeType); + if (componentInstancesOfComponent.isLeft() && !componentInstancesOfComponent.left().value().left.isEmpty()) { + List componentInstances = componentInstancesOfComponent.left().value().left; + for (ComponentInstance componentInstance : componentInstances) { + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(compInstNodeType), componentInstance.getUniqueId(), + GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class); + + if (childrenNodes.isLeft() && !childrenNodes.left().value().isEmpty()) { + List> list = childrenNodes.left().value(); + for (ImmutablePair calculatedCap : list) { + + GraphEdge edge = calculatedCap.right; + Map properties = edge.getProperties(); + String source = null; + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.SOURCE.getProperty())) { + source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + } + String minOccurrences = CapabilityData.MIN_OCCURRENCES; + String occurrences = CapabilityData.MAX_OCCURRENCES; + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty())) { + minOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty())) { + occurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + } + + String capabilityName = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + Either createRelation = createCalculatedCapabilityEdge(componentInstanceData, source, capabilityName, calculatedCap.left, componentInstance.getUniqueId(), minOccurrences, occurrences); + if (createRelation.isLeft()) { + graphRelations.add(createRelation.left().value()); + } + } + } + } + } + } + + private TitanOperationStatus createCalculatedCapabilityRelationsFromComponent(TitanVertex componentInstanceVertex, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, String compInstOriginId) { + + Either, List>, TitanOperationStatus> componentInstancesOfComponent = getComponentInstancesOfComponent(compInstOriginId, containerNodeType, compInstNodeType); + if (componentInstancesOfComponent.isLeft() && !componentInstancesOfComponent.left().value().left.isEmpty()) { + List componentInstances = componentInstancesOfComponent.left().value().left; + for (ComponentInstance componentInstance : componentInstances) { + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(compInstNodeType), componentInstance.getUniqueId(), + GraphEdgeLabels.CALCULATED_CAPABILITY); + + if (childrenNodes.isLeft() && !childrenNodes.left().value().isEmpty()) { + List> list = childrenNodes.left().value(); + for (ImmutablePair calculatedCap : list) { + + Edge edge = calculatedCap.right; + Map properties = titanGenericDao.getProperties(edge); + String source = null; + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.SOURCE.getProperty())) { + source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + } + String minOccurrences = CapabilityData.MIN_OCCURRENCES; + String occurrences = CapabilityData.MAX_OCCURRENCES; + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty())) { + minOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty())) { + occurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + } + + String capabilityName = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + TitanOperationStatus createRelation = createCalculatedCapabilityEdge(componentInstanceVertex, source, capabilityName, calculatedCap.left, componentInstance.getUniqueId(), minOccurrences, occurrences); + if (!createRelation.equals(TitanOperationStatus.OK)) { + return createRelation; + } + } + } + } + } + return TitanOperationStatus.OK; + } + + private void createCaculatedRelationsFromAtomicResource(ComponentInstanceData componentInstanceData, List graphRelations, String compInstOriginId) { + + Map capabilities = new HashMap(); + Set caseInsensitiveCapNames = new HashSet<>(); + TitanOperationStatus getAllCapabilities = capabilityOperation.getAllCapabilitiesRecusive(NodeTypeEnum.Resource, compInstOriginId, true, capabilities, caseInsensitiveCapNames, true); + + if (!getAllCapabilities.equals(TitanOperationStatus.OK)) { + if (getAllCapabilities != TitanOperationStatus.NOT_FOUND) { + log.debug("Couldn't fetch capabilities of component {}, error: {}", compInstOriginId, getAllCapabilities); + return; + } + } + log.trace("Found {} capabilities for component {}, ", capabilities.size(), compInstOriginId); + for (Entry capPair : capabilities.entrySet()) { + CapabilityDefinition capabilityData = capPair.getValue(); + log.trace("Creating calculated capability relation from component instance {} to capability {}", componentInstanceData.getUniqueId(), capabilityData.getUniqueId()); + CapabilityData capabilityDataNode = new CapabilityData(); + capabilityDataNode.setUniqueId(capabilityData.getUniqueId()); + String minOccurrences = CapabilityData.MIN_OCCURRENCES; + String occurrences = CapabilityData.MAX_OCCURRENCES; + if (capabilityData.getMinOccurrences() != null) { + minOccurrences = capabilityData.getMinOccurrences(); + } + if (capabilityData.getMinOccurrences() != null) { + occurrences = capabilityData.getMaxOccurrences(); + } + + Either createRelation = createCalculatedCapabilityEdge(componentInstanceData, compInstOriginId, capPair.getKey(), capabilityDataNode, componentInstanceData.getUniqueId(), minOccurrences, occurrences); + graphRelations.add(createRelation.left().value()); + } + } + + private TitanOperationStatus createCaculatedRelationsFromAtomicResource(TitanVertex componentInstanceVertex, String compInstOriginId) { + + Map capabilities = new HashMap(); + Set caseInsensitiveCapNames = new HashSet<>(); + TitanOperationStatus getAllCapabilities = capabilityOperation.getAllCapabilitiesRecusive(NodeTypeEnum.Resource, compInstOriginId, true, capabilities, caseInsensitiveCapNames, true); + + if (!getAllCapabilities.equals(TitanOperationStatus.OK)) { + if (getAllCapabilities != TitanOperationStatus.NOT_FOUND) { + log.debug("Couldn't fetch capabilities of component {}, error: {}", compInstOriginId, getAllCapabilities); + } + } + log.trace("Found {} capabilities for component {}, ", capabilities.size(), compInstOriginId); + String compoInstId = (String) titanGenericDao.getProperty(componentInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + for (Entry capPair : capabilities.entrySet()) { + CapabilityDefinition capabilityData = capPair.getValue(); + log.trace("Creating calculated capability relation from component instance {} to capability {}", compoInstId, capabilityData.getUniqueId()); + CapabilityData capabilityDataNode = new CapabilityData(); + capabilityDataNode.setUniqueId(capabilityData.getUniqueId()); + String minOccurrences = CapabilityData.MIN_OCCURRENCES; + String occurrences = CapabilityData.MAX_OCCURRENCES; + if (capabilityData.getMinOccurrences() != null) { + minOccurrences = capabilityData.getMinOccurrences(); + } + if (capabilityData.getMinOccurrences() != null) { + occurrences = capabilityData.getMaxOccurrences(); + } + + TitanOperationStatus createRelation = createCalculatedCapabilityEdge(componentInstanceVertex, compInstOriginId, capPair.getKey(), capabilityDataNode, compoInstId, minOccurrences, occurrences); + if (!createRelation.equals(TitanOperationStatus.OK)) { + return createRelation; + } + } + return TitanOperationStatus.OK; + } + + private Either createCalculatedCapabilityEdge(ComponentInstanceData componentInstanceData, String compInstOriginId, String capabilityName, CapabilityData capabilityDataNode, String componentInstanceId, + String minOccurrences, String occurrences) { + Map props = prepareEdgeCapabiltyProperites(compInstOriginId, capabilityName, componentInstanceId, minOccurrences, occurrences); + + Either createRelation = titanGenericDao.createRelation(componentInstanceData, capabilityDataNode, GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (createRelation.isRight()) { + TitanOperationStatus titanOperationStatus = createRelation.right().value(); + log.debug("Failed to create calculated capability from component instance {} to capability {}, error: {}", componentInstanceData.getUniqueId(), capabilityDataNode.getUniqueId(), titanOperationStatus); + return Either.right(titanOperationStatus); + } + return createRelation; + } + + private TitanOperationStatus createCalculatedCapabilityEdge(TitanVertex componentInstanceVertex, String compInstOriginId, String capabilityName, CapabilityData capabilityDataNode, String componentInstanceId, String minOccurrences, + String occurrences) { + Map props = prepareEdgeCapabiltyProperites(compInstOriginId, capabilityName, componentInstanceId, minOccurrences, occurrences); + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, capabilityDataNode, GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated capability from component instance {} to capability {}, error: {}", componentInstanceId, capabilityDataNode.getUniqueId(), createRelation); + } + return createRelation; + } + + private TitanOperationStatus createCalculatedCapabilityEdge(TitanVertex componentInstanceVertex, String compInstOriginId, String capabilityName, TitanVertex capabilityDataVertex, String componentInstanceId, String minOccurrences, + String occurrences) { + Map props = prepareEdgeCapabiltyProperites(compInstOriginId, capabilityName, componentInstanceId, minOccurrences, occurrences); + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, capabilityDataVertex, GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated capability from component instance {} to capability {}, error: {}", componentInstanceId, capabilityName, createRelation); + } + return createRelation; + } + + private Map prepareEdgeCapabiltyProperites(String compInstOriginId, String capabilityName, String componentInstanceId, String minOccurrences, String occurrences) { + Map props = new HashMap(); + if (capabilityName != null) + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capabilityName); + if (compInstOriginId != null) + props.put(GraphEdgePropertiesDictionary.SOURCE.getProperty(), compInstOriginId); + if (componentInstanceId != null) { + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), componentInstanceId); + } + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), minOccurrences); + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), occurrences); + return props; + } + + private Either createCalculatedRequirementEdge(ComponentInstanceData componentInstanceData, String compInstOriginId, String capabilityName, RequirementData requirementData, ComponentInstance componentInstance, + String occurrences, String minOccurrences) { + Map props = new HashMap(); + if (capabilityName != null) + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capabilityName); + if (compInstOriginId != null) + props.put(GraphEdgePropertiesDictionary.SOURCE.getProperty(), compInstOriginId); + if (componentInstance != null) { + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), componentInstance.getUniqueId()); + } + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), occurrences); + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), minOccurrences); + + Either createRelation = titanGenericDao.createRelation(componentInstanceData, requirementData, 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: {}", componentInstanceData.getUniqueId(), requirementData.getUniqueId(), titanOperationStatus); + return Either.right(titanOperationStatus); + } + return createRelation; + } + + private TitanOperationStatus createCalculatedRequirementEdge(TitanVertex componentInstanceVertex, String compInstOriginId, String capabilityName, TitanVertex requirementVertex, ComponentInstance componentInstance, String occurrences, + String minOccurrences) { + Map props = new HashMap(); + if (capabilityName != null) + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capabilityName); + if (compInstOriginId != null) + props.put(GraphEdgePropertiesDictionary.SOURCE.getProperty(), compInstOriginId); + if (componentInstance != null) { + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), componentInstance.getUniqueId()); + } + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), occurrences); + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), minOccurrences); + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, requirementVertex, GraphEdgeLabels.CALCULATED_REQUIREMENT, props); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated requirement from component instance {} to requirement {}, error: {}", componentInstance.getUniqueId(), capabilityName, createRelation); + return createRelation; + } + return createRelation; + } + + /** + * Make a relation between service to resource instance. + * + * @param containerCompIdData + * @param componentInstanceData + * @param logicalName + * @return + */ + private Either associateContainerCompToComponentInstance(UniqueIdData containerCompIdData, ComponentInstanceData componentInstanceData, String logicalName) { + Map properties = new HashMap(); + + properties.put(GraphPropertiesDictionary.NAME.getProperty(), logicalName); + Either createRelation = titanGenericDao.createRelation(containerCompIdData, componentInstanceData, GraphEdgeLabels.RESOURCE_INST, properties); + + log.debug("After associating container component {} to resource instance {} with logical name {}. Status is {}", containerCompIdData.getUniqueId(), componentInstanceData.getUniqueId(), logicalName, createRelation); + + return createRelation; + } + + private TitanOperationStatus associateContainerCompToComponentInstance(TitanVertex containerCompVertex, TitanVertex componentInstanceVertex, String logicalName) { + Map properties = new HashMap(); + + properties.put(GraphPropertiesDictionary.NAME.getProperty(), logicalName); + TitanOperationStatus createRelation = titanGenericDao.createEdge(containerCompVertex, componentInstanceVertex, GraphEdgeLabels.RESOURCE_INST, properties); + + return createRelation; + } + + @Override + public String createComponentInstLogicalName(String instanceNumber, String componentInstanceName) { + + String logicalName = buildComponentInstanceLogicalName(instanceNumber, componentInstanceName); + + return logicalName; + } + + private String buildComponentInstanceLogicalName(String instanceNumber, String lastToken) { + return lastToken + " " + (instanceNumber == null ? 0 : instanceNumber); + } + + private ComponentInstanceData buildComponentInstanceData(ComponentInstance resourceInstance, String componentId, String logicalName) { + + String ciOriginComponentUid = resourceInstance.getComponentUid(); + + ComponentInstanceDataDefinition dataDefinition = new ComponentInstanceDataDefinition(resourceInstance); + + Long creationDate = resourceInstance.getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + dataDefinition.setCreationTime(creationDate); + dataDefinition.setModificationTime(creationDate); + // dataDefinition.setResourceUid(resourceUid); + // String replacmentlogicalName = logicalName.replaceAll(" ", + // "_").toLowerCase(); + dataDefinition.setName(logicalName); + if (dataDefinition.getNormalizedName() == null) + dataDefinition.setNormalizedName(ValidationUtils.normaliseComponentInstanceName(logicalName)); + dataDefinition.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(componentId, ciOriginComponentUid, dataDefinition.getNormalizedName())); + + ComponentInstanceData resourceInstanceData = new ComponentInstanceData(dataDefinition); + + return resourceInstanceData; + } + + public Either removeComponentInstanceFromComponent(NodeTypeEnum containerNodeType, String containerComponentId, String componentInstanceUid) { + + log.debug("Going to delete component instance {} under component {}", componentInstanceUid, containerComponentId); + + Either node = findResourceInstance(componentInstanceUid); + + if (node.isRight()) { + TitanOperationStatus status = node.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Remove Component Instance"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Remove Component Instance"); + log.debug("Failed to delete component instance {}. Status is {}", componentInstanceUid, status); + return Either.right(status); + } + + TitanOperationStatus isComponentInstOfComponent = verifyResourceInstanceUnderComponent(containerNodeType, containerComponentId, componentInstanceUid); + if (isComponentInstOfComponent != TitanOperationStatus.OK) { + return Either.right(isComponentInstOfComponent); + } + + TitanOperationStatus status = deleteOutgoingRelationships(containerNodeType, containerComponentId, componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + status = deleteIncomingRelationships(containerNodeType, containerComponentId, componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + // delete associated properties + status = deleteAssociatedProperties(componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + // delete associated properties + status = deleteAssociatedAttributes(componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + // delete associated artifacts + status = deleteAssociatedArtifacts(componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + // delete associated capability instances + if (containerNodeType.equals(NodeTypeEnum.Resource)) { + status = deleteAssociatedCapabilityInstances(componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + } + Either deleteRI = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), componentInstanceUid, ComponentInstanceData.class); + + if (deleteRI.isRight()) { + TitanOperationStatus deleteRiStatus = deleteRI.right().value(); + log.error("Failed to delete resource instance {}. Status is {}", componentInstanceUid, deleteRiStatus); + return Either.right(deleteRiStatus); + } + + ComponentInstanceData deletedResourceInst = deleteRI.left().value(); + + ComponentInstance resourceInstance = new ComponentInstance(deletedResourceInst.getComponentInstDataDefinition()); + + return Either.left(resourceInstance); + } + + private TitanOperationStatus deleteAssociatedCapabilityInstances(String resourceInstanceId) { + TitanOperationStatus status = TitanOperationStatus.OK; + + log.debug("Before deleting all capability instances of component istance {}.", resourceInstanceId); + Either>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + + if (getCapabilityInstancesRes.isRight() && !getCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + status = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability Instances of resource instance {}. Status is {}", resourceInstanceId, status); + } + if (getCapabilityInstancesRes.isLeft()) { + for (ImmutablePair capabilityInstancePair : getCapabilityInstancesRes.left().value()) { + Either deleteCababilityInstanceRes = capabilityInstanceOperation.deleteCapabilityInstanceFromResourceInstance(resourceInstanceId, capabilityInstancePair.getLeft().getUniqueId()); + if (deleteCababilityInstanceRes.isRight()) { + status = deleteCababilityInstanceRes.right().value(); + } + } + } + log.debug("After deleting all capability instances of component istance {}. Status is {}", resourceInstanceId, status); + return status; + } + + private TitanOperationStatus deleteAssociatedArtifacts(String resourceInstanceUid) { + + Either>, TitanOperationStatus> artifactRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceUid, GraphEdgeLabels.ARTIFACT_REF, + NodeTypeEnum.ArtifactRef, ArtifactData.class); + + if (artifactRes.isRight()) { + TitanOperationStatus status = artifactRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find artifacts of resource instance {}. Status is {}", resourceInstanceUid, status); + return status; + } + } else { + + List> artifactPairs = artifactRes.left().value(); + for (ImmutablePair pair : artifactPairs) { + String uniqueId = (String) pair.left.getUniqueId(); + Either removeArifactFromGraph = artifactOperation.removeArtifactOnGraph(resourceInstanceUid, uniqueId, NodeTypeEnum.ResourceInstance, resourceInstanceUid, true); + if (removeArifactFromGraph.isRight()) { + TitanOperationStatus status = removeArifactFromGraph.right().value(); + log.error("Failed to delete artifact of resource instance {}. Status is {}", resourceInstanceUid, status); + return status; + } + + } + } + + return TitanOperationStatus.OK; + + } + + private TitanOperationStatus deleteAssociatedProperties(String resourceInstanceUid) { + final GraphEdgeLabels edgeConectingToRI = GraphEdgeLabels.PROPERTY_VALUE; + final NodeTypeEnum elementTypeToDelete = NodeTypeEnum.PropertyValue; + return deleteAssociatedRIElements(elementTypeToDelete, edgeConectingToRI, resourceInstanceUid, () -> PropertyValueData.class); + + } + + private TitanOperationStatus deleteAssociatedAttributes(String resourceInstanceUid) { + final GraphEdgeLabels edgeConectingToRI = GraphEdgeLabels.ATTRIBUTE_VALUE; + final NodeTypeEnum elementTypeToDelete = NodeTypeEnum.AttributeValue; + return deleteAssociatedRIElements(elementTypeToDelete, edgeConectingToRI, resourceInstanceUid, () -> AttributeValueData.class); + } + + private TitanOperationStatus deleteAssociatedRIElements(NodeTypeEnum elementTypeToDelete, GraphEdgeLabels edgeConectingToRI, String resourceInstanceUid, Supplier> classGen) { + + Either>, TitanOperationStatus> elementsNodesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceUid, edgeConectingToRI, elementTypeToDelete, + classGen.get()); + + if (elementsNodesRes.isRight()) { + TitanOperationStatus status = elementsNodesRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logInternalFlowError("deleteAssociatedRIElements", "Failed to find the elements of resource instance " + resourceInstanceUid + ". status is " + status, ErrorSeverity.ERROR); + return status; + } + } else { + + List> relationshipNodes = elementsNodesRes.left().value(); + if (relationshipNodes != null) { + for (ImmutablePair immutablePair : relationshipNodes) { + T elementValueDataData = immutablePair.getKey(); + Either deleteNode = titanGenericDao.deleteNode(elementValueDataData, classGen.get()); + if (deleteNode.isRight()) { + TitanOperationStatus status = deleteNode.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("deleteAssociatedRIElements", "Failed to delete element value node " + elementValueDataData + ". status is " + status, ErrorSeverity.ERROR); + return status; + } + } + } + + } + + return TitanOperationStatus.OK; + } + + /** + * delete all relationship instance nodes which has an outgoing edge to a given resource instance + * + * @param resourceInstanceUid + * @return + */ + private TitanOperationStatus deleteIncomingRelationships(NodeTypeEnum componentType, String componentId, String resourceInstanceUid) { + + Either, TitanOperationStatus> relationsForTarget = getRelationsForTarget(resourceInstanceUid); + if (relationsForTarget.isRight()) { + TitanOperationStatus status = relationsForTarget.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the relationships of resource instance {}. Status is {}", resourceInstanceUid, status); + return status; + } + } else { + List relList = relationsForTarget.left().value(); + for (RequirementCapabilityRelDef relation : relList) { + Either dissociateResourceInstances = dissociateResourceInstances(componentId, componentType, relation, true); + if (dissociateResourceInstances.isRight()) { + log.error("failed to diassociate component instance {} and component instance {} under component {}. error is {}", relation.getFromNode(), relation.getToNode(), componentId); + return TitanOperationStatus.GENERAL_ERROR; + } + } + } + return TitanOperationStatus.OK; + } + + /** + * delete all relationship instance nodes which has an incoming edge from a given resource instance + * + * @param resourceInstanceUid + * @return + */ + private TitanOperationStatus deleteOutgoingRelationships(NodeTypeEnum componentType, String componentId, String resourceInstanceUid) { + + Either, TitanOperationStatus> relationsForSource = getRelationsForSource(resourceInstanceUid); + if (relationsForSource.isRight()) { + TitanOperationStatus status = relationsForSource.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the relationships of resource instance " + resourceInstanceUid + ". status is " + status); + return status; + } + } else { + List relList = relationsForSource.left().value(); + for (RequirementCapabilityRelDef relation : relList) { + Either dissociateResourceInstances = dissociateResourceInstances(componentId, componentType, relation, true); + if (dissociateResourceInstances.isRight()) { + log.error("failed to diassociate component instance {} and component instance {} under component {}. error is {}", relation.getFromNode(), relation.getToNode(), componentId); + return TitanOperationStatus.GENERAL_ERROR; + } + } + } + return TitanOperationStatus.OK; + } + + /** + * delete relationship instance nodes + * + * @param relationshipNodes + * @return + */ + private TitanOperationStatus deleteRelationshipNodes(List> relationshipNodes) { + + if (relationshipNodes != null) { + for (ImmutablePair immutablePair : relationshipNodes) { + RelationshipInstData relationshipTypeImplData = immutablePair.getKey(); + Either deleteNode = titanGenericDao.deleteNode(relationshipTypeImplData, RelationshipInstData.class); + if (deleteNode.isRight()) { + TitanOperationStatus status = deleteNode.right().value(); + log.error("Failed to delete relationship node {}. Status is {}", relationshipTypeImplData, status); + return status; + } + } + } + + return TitanOperationStatus.OK; + } + + public Either, TitanOperationStatus> disconnectResourcesInService(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef) { + + if (requirementDef.getRelationships() == null) { + log.debug("No relation pair in request [ {} ]", requirementDef); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + + String fromResInstanceUid = requirementDef.getFromNode(); + String toResInstanceUid = requirementDef.getToNode(); + + // DE191707 + TitanOperationStatus isResourceInstOfService = verifyResourceInstanceUnderComponent(nodeType, componentId, fromResInstanceUid); + if (isResourceInstOfService != TitanOperationStatus.OK) { + return Either.right(isResourceInstOfService); + } + isResourceInstOfService = verifyResourceInstanceUnderComponent(nodeType, componentId, toResInstanceUid); + if (isResourceInstOfService != TitanOperationStatus.OK) { + return Either.right(isResourceInstOfService); + } + + List relationPairList = requirementDef.getRelationships(); + + Either riFrom = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), fromResInstanceUid); + if (riFrom.isRight()) { + log.debug("Failed to fetch component instance {}. Error: {}", fromResInstanceUid, riFrom.right().value()); + return Either.right(riFrom.right().value()); + } + Iterator edgeIter = riFrom.left().value().edges(Direction.OUT, GraphEdgeLabels.RELATIONSHIP_INST.getProperty()); + if (edgeIter == null) { + log.debug("No edges with label {} for owner RI {}", GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED.getProperty(), fromResInstanceUid); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + List deletedRelations = new ArrayList<>(); + List vertexToDelete = new ArrayList<>(); + while (edgeIter.hasNext()) { + TitanEdge edge = (TitanEdge) edgeIter.next(); + String name = (String) edge.property(GraphEdgePropertiesDictionary.NAME.getProperty()).value(); + for (RequirementAndRelationshipPair relationPair : relationPairList) { + if (relationPair.getRequirement().equals(name)) { + TitanVertex inVertex = edge.inVertex(); + String requirementId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.REQUIREMENT_ID.getProperty()); + String capabiltyId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.CAPABILITY_ID.getProperty()); + String requirementOwnerId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.REQUIREMENT_OWNER_ID.getProperty()); + String capabiltyOwnerId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.CAPABILITY_OWNER_ID.getProperty()); + String relationVertexId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + // verify vs requirement id and owner ids. ( for + // requirements with same name) + if (requirementId.equals(relationPair.getRequirementUid()) && capabiltyId.equals(relationPair.getCapabilityUid()) && requirementOwnerId.equals(relationPair.getRequirementOwnerId()) + && capabiltyOwnerId.equals(relationPair.getCapabilityOwnerId())) { + vertexToDelete.add(relationVertexId); + } + } + } + } + log.debug("relation node with ids: {} are going to be deleted", vertexToDelete); + for (String relationVertexId : vertexToDelete) { + // remove relation vertex + Either relationNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipInst), relationVertexId, RelationshipInstData.class); + if (relationNode.isRight()) { + log.debug("Failed to delete relation node with id {}. Error: {}", relationVertexId, relationNode.right().value()); + return Either.right(relationNode.right().value()); + } + RelationshipInstData deletedRelation = relationNode.left().value(); + deletedRelations.add(deletedRelation); + } + if (deletedRelations.size() > 0) { + return Either.left(deletedRelations); + } + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + @Override + public Either dissociateResourceInstances(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef, boolean inTransaction) { + + String fromResInstanceUid = requirementDef.getFromNode(); + String toResInstanceUid = requirementDef.getToNode(); + String requirement = requirementDef.getRelationships().get(0).getRequirement(); + Either result = null; + try { + + Either, TitanOperationStatus> dissociateRes = disconnectResourcesInService(componentId, nodeType, requirementDef); + if (dissociateRes.isRight()) { + TitanOperationStatus status = dissociateRes.right().value(); + log.error("Failed to dissociate resource instance " + fromResInstanceUid + " from resource instance " + toResInstanceUid + " in service " + componentId + ". status is " + status); + BeEcompErrorManager.getInstance().logBeDaoSystemError("dissociateComponentInstances"); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + StorageOperationStatus updateCalculatedCapReqResult = updateCalculatedCapReq(requirementDef, false); + if (!updateCalculatedCapReqResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "dissociateComponentInstances"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("dissociateComponentInstances"); + log.debug("Failed to dissociate component instances {}. Status is {}", requirementDef, updateCalculatedCapReqResult); + result = Either.right(updateCalculatedCapReqResult); + return result; + } + + // RelationshipInstData relationshipInstData = + // dissociateRes.left().value(); + List relationshipInstData = dissociateRes.left().value(); + RequirementCapabilityRelDef capabilityRelDef = buildCapabilityResult(fromResInstanceUid, toResInstanceUid, requirement, relationshipInstData); + + result = Either.left(capabilityRelDef); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + + } + + private StorageOperationStatus updateCalculatedCapReq(RequirementCapabilityRelDef capabilityRelDef, boolean associate) { + GraphEdgeLabels requirmentNewLabel = associate ? GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED : GraphEdgeLabels.CALCULATED_REQUIREMENT; + + GraphEdgeLabels requirmentCurrentLabel = associate ? GraphEdgeLabels.CALCULATED_REQUIREMENT : GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED; + + GraphEdgeLabels capabilityNewLabel = associate ? GraphEdgeLabels.CALCULATED_CAPABILITY_FULLFILLED : GraphEdgeLabels.CALCULATED_CAPABILITY; + + GraphEdgeLabels capabilityCurrentLabel = associate ? GraphEdgeLabels.CALCULATED_CAPABILITY : GraphEdgeLabels.CALCULATED_CAPABILITY_FULLFILLED; + + List relationships = capabilityRelDef.getRelationships(); + for (RequirementAndRelationshipPair pair : relationships) { + StorageOperationStatus status = updateRequirementEdges(requirmentNewLabel, requirmentCurrentLabel, pair, capabilityRelDef.getFromNode()); + if (!status.equals(StorageOperationStatus.OK)) { + return status; + } + status = updateCapabiltyEdges(capabilityNewLabel, capabilityCurrentLabel, pair, capabilityRelDef.getToNode()); + if (!status.equals(StorageOperationStatus.OK)) { + return status; + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus updateRequirementEdges(GraphEdgeLabels requirmentNewLabel, GraphEdgeLabels requirmentCurrentLabel, RequirementAndRelationshipPair pair, String requirementOwnerId) { + Either reqOwnerRI = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), requirementOwnerId); + if (reqOwnerRI.isRight()) { + log.debug("Failed to fetch requirment Owner by Id {}. Error: {}", requirementOwnerId, reqOwnerRI.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(reqOwnerRI.right().value()); + } + Iterator edgeIter = reqOwnerRI.left().value().edges(Direction.OUT, requirmentCurrentLabel.name(), requirmentNewLabel.name()); + if (edgeIter == null) { + log.debug("No edges with label {} for woner RI {}", requirmentCurrentLabel, requirementOwnerId); + return StorageOperationStatus.GENERAL_ERROR; + } + boolean associate = requirmentNewLabel.equals(GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED) ? true : false; + while (edgeIter.hasNext()) { + TitanEdge edge = (TitanEdge) edgeIter.next(); + String name = (String) edge.property(GraphEdgePropertiesDictionary.NAME.getProperty()).value(); + if (pair.getRequirement().equals(name)) { + TitanVertex reqVertex = edge.inVertex(); + String requirementId = (String) titanGenericDao.getProperty(reqVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + // verify vs requirement id . ( for requirements with same name) + if (requirementId.equals(pair.getRequirementUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(pair.getRequirementOwnerId())) { + String requiredOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + String leftOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + + String requiredOccurrencesNew = "0"; + String leftOccurrencesNew = RequirementData.MAX_DEFAULT_OCCURRENCES; + if (requiredOccurrences != null) { + Integer iOccurrences = Integer.parseInt(requiredOccurrences); + if (associate) { + if (iOccurrences > 0) { + iOccurrences--; + requiredOccurrencesNew = iOccurrences.toString(); + } + } else { + String reqMinOccurrences = (String) titanGenericDao.getProperty(reqVertex, GraphPropertiesDictionary.MIN_OCCURRENCES.getProperty()); + if (reqMinOccurrences == null) { + reqMinOccurrences = RequirementData.MIN_OCCURRENCES; + } + if (Integer.parseInt(reqMinOccurrences) > iOccurrences) { + iOccurrences++; + requiredOccurrencesNew = iOccurrences.toString(); + } + } + } + Map properties = titanGenericDao.getProperties(edge); + properties.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), requiredOccurrencesNew); + + if (leftOccurrences != null && !leftOccurrences.equals(RequirementData.MAX_OCCURRENCES)) { + Integer iOccurrences = Integer.parseInt(leftOccurrences); + if (associate) { + if (iOccurrences > 0) { + iOccurrences--; + } + } else { + iOccurrences++; + } + leftOccurrencesNew = iOccurrences.toString(); + properties.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), leftOccurrencesNew); + if ((associate && iOccurrences == 0) || (!associate && iOccurrences == 1)) { + // move edge to full filled state + TitanVertex outVertex = edge.outVertex(); + TitanEdge newEdge = outVertex.addEdge(requirmentNewLabel.getProperty(), reqVertex); + titanGenericDao.setProperties(newEdge, properties); + edge.remove(); + } else { + titanGenericDao.setProperties(edge, properties); + } + } else { + leftOccurrencesNew = leftOccurrences; + properties.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), leftOccurrencesNew); + titanGenericDao.setProperties(edge, properties); + } + break; + } + } + } + } + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus updateCapabiltyEdges(GraphEdgeLabels capabiltyNewLabel, GraphEdgeLabels capabiltyCurrentLabel, RequirementAndRelationshipPair pair, String capabiltyOwnerId) { + Either capOwnerRI = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), capabiltyOwnerId); + if (capOwnerRI.isRight()) { + log.debug("Failed to fetch requirment Owner by Id {}. Error: {}", capabiltyOwnerId, capOwnerRI.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(capOwnerRI.right().value()); + } + Iterator edgeIter = capOwnerRI.left().value().edges(Direction.OUT, capabiltyCurrentLabel.name(), capabiltyNewLabel.name()); + if (edgeIter == null) { + log.debug("No edges with label {} for owner RI {}", capabiltyCurrentLabel, capabiltyOwnerId); + return StorageOperationStatus.GENERAL_ERROR; + } + boolean associate = capabiltyNewLabel.equals(GraphEdgeLabels.CALCULATED_CAPABILITY_FULLFILLED) ? true : false; + + while (edgeIter.hasNext()) { + TitanEdge edge = (TitanEdge) edgeIter.next(); + TitanVertex capVertex = edge.inVertex(); + // edge.property(GraphEdgePropertiesDictionary.NAME.getProperty()).value(); + + String capabiltyId = (String) titanGenericDao.getProperty(capVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + // verify vs capability id . ( for capabilty with same name) + if (capabiltyId.equals(pair.getCapabilityUid())) { + String ownerIdOnEdge = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(pair.getCapabilityOwnerId())) { + + String requiredOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + String leftOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + + String requiredOccurrencesNew = "0"; + String leftOccurrencesNew = CapabilityData.MAX_OCCURRENCES; + if (requiredOccurrences != null) { + Integer iOccurrences = Integer.parseInt(requiredOccurrences); + if (associate) { + if (iOccurrences > 0) { + iOccurrences--; + requiredOccurrencesNew = iOccurrences.toString(); + } + } else { + String reqMinOccurrences = (String) titanGenericDao.getProperty(capVertex, GraphPropertiesDictionary.MIN_OCCURRENCES.getProperty()); + if (reqMinOccurrences == null) { + reqMinOccurrences = CapabilityData.MIN_OCCURRENCES; + } + if (Integer.parseInt(reqMinOccurrences) > iOccurrences) { + iOccurrences++; + requiredOccurrencesNew = iOccurrences.toString(); + } + } + } + Map properties = titanGenericDao.getProperties(edge); + properties.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), requiredOccurrencesNew); + + if (leftOccurrences != null && !leftOccurrences.equals(CapabilityData.MAX_OCCURRENCES)) { + Integer iOccurrences = Integer.parseInt(leftOccurrences); + if (associate) { + if (iOccurrences > 0) { + iOccurrences--; + } + } else { + iOccurrences++; + } + leftOccurrencesNew = iOccurrences.toString(); + properties.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), leftOccurrencesNew); + if ((associate && iOccurrences == 0) || (!associate && iOccurrences == 1)) { + // move edge to full filled state + TitanVertex outVertex = edge.outVertex(); + TitanEdge newEdge = outVertex.addEdge(capabiltyNewLabel.getProperty(), capVertex); + titanGenericDao.setProperties(newEdge, properties); + edge.remove(); + } else { + titanGenericDao.setProperties(edge, properties); + } + } else { + properties.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), leftOccurrencesNew); + titanGenericDao.setProperties(edge, properties); + } + break; + } + } + } + return StorageOperationStatus.OK; + } + + @Override + public Either dissociateResourceInstances(String serviceId, NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef) { + + return dissociateResourceInstances(serviceId, nodeType, requirementDef, false); + } + + private RequirementCapabilityRelDef buildCapabilityResult(String fromResInstanceUid, String toResInstanceUid, String requirement, List relationshipInstDataList) { + + RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef(); + capabilityRelDef.setFromNode(fromResInstanceUid); + capabilityRelDef.setToNode(toResInstanceUid); + List relationships = new ArrayList(); + for (RelationshipInstData relationshipInstData : relationshipInstDataList) { + RelationshipImpl relationshipImpl = new RelationshipImpl(); + relationshipImpl.setType(relationshipInstData.getType()); + RequirementAndRelationshipPair reqRel = new RequirementAndRelationshipPair(requirement, relationshipImpl); + capabilityRelDef.setRelationships(relationships); + reqRel.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId()); + reqRel.setCapabilityUid(relationshipInstData.getCapabiltyId()); + reqRel.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId()); + reqRel.setRequirementUid(relationshipInstData.getRequirementId()); + relationships.add(reqRel); + } + return capabilityRelDef; + + } + + public Either connectResourcesInService(String componentId, NodeTypeEnum nodeType, String fromResInstanceUid, String toResInstanceUid, RequirementAndRelationshipPair relationPair) { + String relationship = null; + String requirement = relationPair.getRequirement(); + if (relationPair.getRelationship() != null) { + relationship = relationPair.getRelationship().getType(); + } + + if (log.isDebugEnabled()) { + log.debug("Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid, toResInstanceUid, componentId, requirement); + } + + Either fromResourceInstDataRes = findMandatoryResourceInstData(fromResInstanceUid); + if (fromResourceInstDataRes.isRight()) { + TitanOperationStatus status = fromResourceInstDataRes.right().value(); + log.error("Failed to find resource instance {}. Status is {}", fromResInstanceUid, status); + return Either.right(status); + } + ComponentInstanceData fromResourceInstanceData = fromResourceInstDataRes.left().value(); + Either toResourceInstDataRes = findMandatoryResourceInstData(toResInstanceUid); + if (toResourceInstDataRes.isRight()) { + TitanOperationStatus status = toResourceInstDataRes.right().value(); + log.error("Failed to find resource instance " + toResInstanceUid + ". status is " + status); + return Either.right(status); + } + ComponentInstanceData toResourceInstanceData = toResourceInstDataRes.left().value(); + // THE component NodeTypeEnum should be sent + TitanOperationStatus isResourceInstOfService = verifyResourceInstanceUnderComponent(nodeType, componentId, fromResInstanceUid); + if (isResourceInstOfService != TitanOperationStatus.OK) { + return Either.right(isResourceInstOfService); + } + isResourceInstOfService = verifyResourceInstanceUnderComponent(nodeType, componentId, toResInstanceUid); + if (isResourceInstOfService != TitanOperationStatus.OK) { + return Either.right(isResourceInstOfService); + } + + Either, TitanOperationStatus> isValidRes = validateRequirementVsCapability(fromResourceInstanceData, toResourceInstanceData, requirement, relationship, relationPair); + if (isValidRes.isRight()) { + TitanOperationStatus status = isValidRes.right().value(); + log.error("Failed to validate requirement {} between resource instance {} to resource instance {}. Status is {}", requirement, fromResInstanceUid, toResInstanceUid, status); + return Either.right(status); + } + + RelationshipTypeData relationshipTypeData = isValidRes.left().value().getKey(); + String capabilityName = isValidRes.left().value().getValue(); + RelationshipInstData relationshipInstData = buildRelationshipInstData(fromResInstanceUid, requirement, relationshipTypeData, relationPair); + Either createNode = createRelationshipInstData(fromResourceInstDataRes.left().value(), relationshipInstData, relationshipTypeData, requirement); + + if (createNode.isRight()) { + return Either.right(createNode.right().value()); + } + RelationshipInstData createdRelInstData = createNode.left().value(); + Either associateResInst = associateRelationshipInstToTarget(toResourceInstDataRes.left().value(), requirement, capabilityName, createdRelInstData); + + if (associateResInst.isRight()) { + TitanOperationStatus status = associateResInst.right().value(); + log.error("Failed to associate relationship instance {} to target node {}. Status is {}", createdRelInstData.getUniqueId(), toResInstanceUid, status); + return Either.right(status); + } + + return Either.left(createNode.left().value()); + } + + private TitanOperationStatus verifyResourceInstanceUnderComponent(NodeTypeEnum containerNodeType, String containerComponentId, String resInstanceUid) { + + Either, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resInstanceUid, GraphEdgeLabels.RESOURCE_INST, + containerNodeType, ComponentMetadataData.class); + + if (parentNode.isRight()) { + TitanOperationStatus status = parentNode.right().value(); + log.error("Failed to find the service associated to the resource instance {}. Status is {}", resInstanceUid, status); + return status; + } + + ImmutablePair componentsRes = parentNode.left().value(); + ComponentMetadataData componentMetadataData = componentsRes.getKey(); + String uniqueId = (String) componentMetadataData.getUniqueId(); + + if (containerComponentId.equals(uniqueId)) { + return TitanOperationStatus.OK; + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeIncorrectServiceError, "Resource Instance - verifyResourceInstanceUnderComponent", containerComponentId); + BeEcompErrorManager.getInstance().logBeIncorrectComponentError("Resource Instance - verifyResourceInstanceUnderComponent", containerNodeType.getName(), containerComponentId); + log.debug("The provided component id {} is not equal to the component ({}) which associated to resource instance {}.", containerComponentId, uniqueId, resInstanceUid); + return TitanOperationStatus.INVALID_ID; + } + + } + + /** + * find the resource instance node in graph. + * + * @param resInstanceUid + * @return + */ + private Either findMandatoryResourceInstData(String resInstanceUid) { + Either resStatus = findResourceInstance(resInstanceUid); + if (resStatus.isRight()) { + TitanOperationStatus status = resStatus.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + return Either.right(status); + } + ComponentInstanceData riData = resStatus.left().value(); + return Either.left(riData); + } + + /** + * associate relationship instance node to the target resource instance node. + * + * @param toResInstance + * @param requirement + * @param relInstData + * @return + */ + private Either associateRelationshipInstToTarget(ComponentInstanceData toResInstance, String requirement, String capabilityName, RelationshipInstData relInstData) { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + Either createRelation = titanGenericDao.createRelation(relInstData, toResInstance, GraphEdgeLabels.CAPABILITY_NODE, props); + log.debug("After creating relation between relationship instance {} to target node {}", relInstData.getUniqueId(), toResInstance.getUniqueId()); + + return createRelation; + + } + + /** + * create reslationship instance node and associate the reosurce instance node to it. + * + * @param resInstance + * @param relationshipInstData + * @param relationshipTypeData + * @param requirementName + * @return + */ + private Either createRelationshipInstData(ComponentInstanceData resInstance, RelationshipInstData relationshipInstData, RelationshipTypeData relationshipTypeData, String requirementName) { + + Either createNode = titanGenericDao.createNode(relationshipInstData, RelationshipInstData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Failed to create relationship instance node in graph. status is {}", status); + return Either.right(status); + } + + RelationshipInstData createdRelationshipInst = createNode.left().value(); + + Map properties = new HashMap(); + properties.put("name", requirementName); + Either createRelation = titanGenericDao.createRelation(resInstance, createdRelationshipInst, GraphEdgeLabels.RELATIONSHIP_INST, properties); + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + log.error("Failed to associate resource instance " + resInstance.getUniqueIdKey() + " to relationship instance " + createdRelationshipInst.getUniqueId() + ". status is " + status); + return Either.right(status); + } + + return Either.left(createdRelationshipInst); + } + + /** + * check whether we can associate resource instances for a given requirement. + * + * 1. check the source resource instance contains the requirement + * + * 2. check the target resource instance contains a capability with the same name as the requirement + * + * @param fromResInstance + * @param toResInstance + * @param requirement + * @param relationship + * @param relationPair + * @return + */ + private Either, TitanOperationStatus> validateRequirementVsCapability(ComponentInstanceData fromResInstance, ComponentInstanceData toResInstance, String requirement, String relationship, + RequirementAndRelationshipPair relationPair) { + + String fromResourceUid = fromResInstance.getComponentInstDataDefinition().getComponentUid(); + + String toResourceUid = toResInstance.getComponentInstDataDefinition().getComponentUid(); + Either capabilityDefinitionE = capabilityOperation.getCapability(relationPair.getCapabilityUid(), true); + if (capabilityDefinitionE.isRight()) { + log.error("The capability cannot be found {}", relationPair.getCapabilityUid()); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + Either requirementDefinitionE = requirementOperation.getRequirement(relationPair.getRequirementUid()); + if (requirementDefinitionE.isRight()) { + log.error("The requirement cannot be found {}" , relationPair.getRequirementUid()); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + RequirementDefinition requirementDefinition = requirementDefinitionE.left().value(); + String fetchedRequirementRelationship = requirementDefinition.getRelationship(); + + String fetchedRequirementCapability = requirementDefinition.getCapability(); + // TODO temporary remove of capability sources validation - uncomment + // after alignment + // String fetchedRequirementNodeName = requirementDefinition.getNode(); + + TitanOperationStatus status = validateAvailableRequirement(fromResInstance, relationPair); + if (!status.equals(TitanOperationStatus.OK)) { + log.error("The requirement isn't available, status {}", status); + return Either.right(status); + } + status = validateAvailableCapabilty(toResInstance, relationPair); + if (!status.equals(TitanOperationStatus.OK)) { + log.error("The capabilty isn't available, status {}", status); + return Either.right(status); + } + Either originCapabilty = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), relationPair.getCapabilityOwnerId(), ComponentInstanceData.class); + if (originCapabilty.isRight()) { + log.error("Failed to fetch the origin resource for capabilty resource instance with id {}, error {}", relationPair.getCapabilityOwnerId(), originCapabilty.right().value()); + return Either.right(originCapabilty.right().value()); + } + // TODO temporary remove of capability sources validation - uncomment + // after alignment + // String originCapabId = + // originCapabilty.left().value().getComponentInstDataDefinition().getComponentUid(); + + // List capabilitySources = new ArrayList<>(); + // TitanOperationStatus capabiltySourcesResult = + // resourceOperation.fillResourceDerivedListFromGraph(originCapabId, + // capabilitySources); + // if (!TitanOperationStatus.OK.equals(capabiltySourcesResult)) { + // log.error("Failed to fill capabilty cources for resource with id " + + // originCapabId + " , error " + capabiltySourcesResult); + // return Either.right(originCapabilty.right().value()); + // } + CapabilityDefinition capabilityDefinition = capabilityDefinitionE.left().value(); + String capabilityName = requirement; + + if (log.isDebugEnabled()) { + log.debug("The capability {} of resource {} appropriates to requiremt {} on resource {}", capabilityDefinition, toResourceUid, requirement, fromResourceUid); + } + String capabilityType = capabilityDefinition.getType(); + + if (false == fetchedRequirementCapability.equals(capabilityType)) { + log.error("The capability type in the requirement ({}) does not equal to the capability on the resource {}({})", fetchedRequirementCapability, toResourceUid, capabilityType); + return Either.right(TitanOperationStatus.MATCH_NOT_FOUND); + } + + // if (fetchedRequirementNodeName != null && + // !capabilitySources.contains(fetchedRequirementNodeName)) { + // log.error("The target resource instance " + toResourceUid + " is not + // of type " + fetchedRequirementNodeName); + // return Either.right(TitanOperationStatus.MATCH_NOT_FOUND); + // } + + RelationshipTypeData relationshipTypeData = new RelationshipTypeData(); + relationshipTypeData.getRelationshipTypeDataDefinition().setType(fetchedRequirementRelationship); + + ImmutablePair result = new ImmutablePair(relationshipTypeData, capabilityName); + return Either.left(result); + } + + private TitanOperationStatus validateAvailableRequirement(ComponentInstanceData fromResInstance, RequirementAndRelationshipPair relationPair) { + Either fromRi = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), fromResInstance.getUniqueId()); + if (fromRi.isRight()) { + log.debug("Failed to fetch component instance {}. Error: {}", fromResInstance.getUniqueId(), fromRi.right().value()); + return fromRi.right().value(); + } + Iterator edgeIter = fromRi.left().value().edges(Direction.OUT, GraphEdgeLabels.CALCULATED_REQUIREMENT.name()); + if (edgeIter == null || !edgeIter.hasNext()) { + log.debug("No available CALCULATED_REQUIREMENT edges. All full filled for RI {}", fromResInstance.getUniqueId()); + return TitanOperationStatus.MATCH_NOT_FOUND; + } + boolean exist = false; + while (edgeIter.hasNext()) { + Edge edge = edgeIter.next(); + TitanVertex reqVertex = (TitanVertex) edge.inVertex(); + String reqId = (String) titanGenericDao.getProperty(reqVertex, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement)); + if (reqId.equals(relationPair.getRequirementUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(relationPair.getRequirementOwnerId())) { + String leftOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null && !leftOccurrences.equals(RequirementData.MAX_OCCURRENCES)) { + Integer leftIntValue = Integer.parseInt(leftOccurrences); + if (leftIntValue > 0) { + exist = true; + } + } else { + exist = true; + } + break; + } + } + } + return exist ? TitanOperationStatus.OK : TitanOperationStatus.MATCH_NOT_FOUND; + } + + private TitanOperationStatus validateAvailableCapabilty(ComponentInstanceData toResInstance, RequirementAndRelationshipPair relationPair) { + Either fromRi = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), toResInstance.getUniqueId()); + if (fromRi.isRight()) { + log.debug("Failed to fetch component instance {}. error {}", toResInstance.getUniqueId(), fromRi.right().value()); + return fromRi.right().value(); + } + Iterator edgeIter = fromRi.left().value().edges(Direction.OUT, GraphEdgeLabels.CALCULATED_CAPABILITY.name()); + if (edgeIter == null || !edgeIter.hasNext()) { + log.debug("No available CALCULATED_CAPABILITY edges. All full filled for RI {}", toResInstance.getUniqueId()); + return TitanOperationStatus.MATCH_NOT_FOUND; + } + boolean exist = false; + while (edgeIter.hasNext()) { + Edge edge = edgeIter.next(); + TitanVertex reqVertex = (TitanVertex) edge.inVertex(); + String capId = (String) titanGenericDao.getProperty(reqVertex, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability)); + if (capId.equals(relationPair.getCapabilityUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(relationPair.getCapabilityOwnerId())) { + String leftOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null && !leftOccurrences.equals(CapabilityData.MAX_OCCURRENCES)) { + Integer leftIntValue = Integer.parseInt(leftOccurrences); + if (leftIntValue > 0) { + exist = true; + } + } else { + exist = true; + } + break; + } + } + } + return exist ? TitanOperationStatus.OK : TitanOperationStatus.NOT_FOUND; + } + + private List> findCapabilityOfType(Map capabilities, String fetchedRequirementCapability) { + + List> result = new ArrayList>(); + + if (capabilities == null) { + return null; + } + + for (Entry entry : capabilities.entrySet()) { + CapabilityDefinition capabilityDefinition = entry.getValue(); + String type = capabilityDefinition.getType(); + if (fetchedRequirementCapability.equals(type)) { + ImmutablePair pair = new ImmutablePair(entry.getKey(), capabilityDefinition); + result.add(pair); + } + } + + return result; + } + + protected TitanOperationStatus validateTheTargetResourceInstance(String fetchedRequirementNodeName, String resourceUid) { + + if (fetchedRequirementNodeName == null) { + return TitanOperationStatus.OK; + } + + List resourcesPathList = new ArrayList(); + TitanOperationStatus status = resourceOperation.findResourcesPathRecursively(resourceUid, resourcesPathList); + if (status != TitanOperationStatus.OK) { + log.error("Failed to find the parent list of resource {}. Status is {}", resourceUid, status); + return status; + } + + boolean found = false; + if (resourcesPathList != null) { + for (ResourceMetadataData resourceData : resourcesPathList) { + String resourceName = resourceData.getMetadataDataDefinition().getName(); + if (fetchedRequirementNodeName.equals(resourceName)) { + found = true; + log.debug("The resource {} is of type {}", resourceData.getUniqueId(), fetchedRequirementNodeName); + break; + } + } + } + + if (true == found) { + return TitanOperationStatus.OK; + } else { + return TitanOperationStatus.MATCH_NOT_FOUND; + } + + } + + private RelationshipInstData buildRelationshipInstData(String fromResInstanceUid, String requirement, RelationshipTypeData relationshipTypeData, RequirementAndRelationshipPair relationPair) { + + RelationshipInstData relationshipInstData = new RelationshipInstData(); + relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, requirement)); + String type = null; + if (relationshipTypeData != null) { + type = relationshipTypeData.getRelationshipTypeDataDefinition().getType(); + } + + relationshipInstData.setType(type); + Long creationDate = System.currentTimeMillis(); + relationshipInstData.setCreationTime(creationDate); + relationshipInstData.setModificationTime(creationDate); + relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId()); + relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId()); + relationshipInstData.setCapabiltyId(relationPair.getCapabilityUid()); + relationshipInstData.setRequirementId(relationPair.getRequirementUid()); + + return relationshipInstData; + } + + private Either findResourceInstance(String resInstanceUid) { + + Either node = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resInstanceUid, ComponentInstanceData.class); + + return node; + + } + + @Override + public Either updateResourceInstance(String serviceId, NodeTypeEnum nodeType, String resourceInstanceUid, ComponentInstance resourceInstance, boolean inTransaction) { + + Either result = null; + try { + + Either updateRes = updateResourceInstanceInService(serviceId, resourceInstanceUid, resourceInstance); + + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + log.error("Failed to update resource instance {}. Status is {}", resourceInstanceUid, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ComponentInstance value = updateRes.left().value(); + + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + + } + + /** + * prepare new resource instance object for update + * + * @param resourceInstance + * @param currentInst + * @return + */ + private ComponentInstance normalizeResourceInstanceForUpdate(ComponentInstance resourceInstance, ComponentInstanceData currentInst) { + + ComponentInstance instance = new ComponentInstance(); + instance.setUniqueId((String) currentInst.getUniqueId()); + Long modificationTime = resourceInstance.getModificationTime(); + if (modificationTime == null) { + modificationTime = System.currentTimeMillis(); + } + instance.setModificationTime(modificationTime); + instance.setPosX(resourceInstance.getPosX()); + instance.setPosY(resourceInstance.getPosY()); + instance.setDescription(resourceInstance.getDescription()); + instance.setName(resourceInstance.getName()); + instance.setNormalizedName(resourceInstance.getNormalizedName()); + instance.setPropertyValueCounter(resourceInstance.getPropertyValueCounter()); + instance.setAttributeValueCounter(resourceInstance.getAttributeValueCounter()); + instance.setInputValueCounter(resourceInstance.getInputValueCounter()); + return instance; + } + + private void printDiff(ComponentInstanceData currentInst, ComponentInstance resourceInstance) { + + log.debug("The current Resource Instance details are : {}", currentInst); + log.debug("The received Resource Instance details for update are : {}", resourceInstance); + + } + + @Override + public Either updateResourceInstance(String serviceId, NodeTypeEnum nodeType, String resourceInstanceName, ComponentInstance resourceInstance) { + + return updateResourceInstance(serviceId, nodeType, resourceInstanceName, resourceInstance, false); + } + + public Either updateResourceInstanceInService(String serviceId, String resourceInstanceUid, ComponentInstance resourceInstance) { + + log.debug("Going to update resource instance {}. Properties are {}", resourceInstanceUid, resourceInstance); + Either findInstRes = findResourceInstance(resourceInstanceUid); + if (findInstRes.isRight()) { + TitanOperationStatus status = findInstRes.right().value(); + log.error("Failed to find resource instance {}. Status is {}", resourceInstanceUid, status); + return Either.right(status); + } + + ComponentInstanceData currentInst = findInstRes.left().value(); + if (log.isDebugEnabled()) { + printDiff(currentInst, resourceInstance); + } + + ComponentInstance resourceInstanceForUpdate = normalizeResourceInstanceForUpdate(resourceInstance, currentInst); + + ComponentInstanceData resourceInstanceData = new ComponentInstanceData(resourceInstanceForUpdate); + + Either updateNodeRes = titanGenericDao.updateNode(resourceInstanceData, ComponentInstanceData.class); + if (updateNodeRes.isRight()) { + TitanOperationStatus status = updateNodeRes.right().value(); + log.error("Failed to update resource instance {}. Status is {}", resourceInstanceUid, status); + return Either.right(status); + } + + ComponentInstanceData value = updateNodeRes.left().value(); + + ComponentInstance instance = new ComponentInstance(value.getComponentInstDataDefinition()); + + return Either.left(instance); + + } + + @Override + public Either, List>, StorageOperationStatus> getAllComponentInstances(String componentId, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, boolean inTransaction) { + + Either, List>, StorageOperationStatus> result = null; + + try { + + Either, List>, TitanOperationStatus> resInstancesOfService = getComponentInstancesOfComponent(componentId, containerNodeType, compInstNodeType); + + log.trace("After fetching resource instances of component {}. result is {}", componentId, resInstancesOfService); + if (resInstancesOfService.isRight()) { + TitanOperationStatus status = resInstancesOfService.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find resource instances of service {}. Status is {}", componentId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ImmutablePair, List> immutablePair = resInstancesOfService.left().value(); + List nodes = immutablePair.getKey(); + if (nodes == null || nodes.isEmpty()) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + result = Either.left(immutablePair); + return result; + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + } + + @Override + public Either isComponentInstanceNameExist(String parentComponentId, NodeTypeEnum nodeType, String compInstId, String componentInstName) { + + Either result = null; + Either updateRes = isComponentInstanceNameExistOnGraph(parentComponentId, nodeType, compInstId, componentInstName); + + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + log.error("Failed to find component instance name {}. Status is {}", componentInstName, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Boolean value = updateRes.left().value(); + + result = Either.left(value); + + return result; + + } + + private Either isComponentInstanceNameExistOnGraph(String parentComponentId, NodeTypeEnum parentNodeType, String compInstId, String componentInstName) { + + Either graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.debug("Failed to retrieve graph. status is {}", graphRes); + return Either.right(graphRes.right().value()); + } + + TitanGraph titanGraph = graphRes.left().value(); + Iterable vertices = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentComponentId).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + TitanVertex serviceVertex = vertices.iterator().next(); + TitanVertexQuery query = serviceVertex.query(); + query = query.labels(GraphEdgeLabels.RESOURCE_INST.getProperty()); + Iterable verts = query.vertices(); + if (verts == null) { + log.debug("No edges in graph for criteria"); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + Iterator vIter = verts.iterator(); + while (vIter.hasNext()) { + Vertex vert = vIter.next(); + String resInstName = vert.value(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty()); + if (resInstName.equals(componentInstName)) { + if (compInstId != null) {// will be null if we got here from + // create + // Update case - skipping if this is the same component + // instance we are updating, that is allowing + // update of the unchanged name on a component instance. + // This is needed to support position only update, since + // name should + // always be passed in update, and in position case, the + // name will be unchanged. + String uniqueId = vert.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (uniqueId.equals(compInstId)) { + continue; + } + } + return Either.left(Boolean.TRUE); + } + } + return Either.left(Boolean.FALSE); + } + + /** + * find resource instances and the relationships between the relationships of a given resource + * + * @param componentId + * @return + */ + public Either, List>, TitanOperationStatus> getComponentInstancesOfComponent(String componentId, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType) { + + if (log.isDebugEnabled()) + log.debug("Going to fetch all resource instances under component {}", componentId); + + Either componentRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(containerNodeType), componentId, ComponentMetadataData.class); + if (componentRes.isRight()) { + TitanOperationStatus status = componentRes.right().value(); + log.error("Failed to find component {}. Status is {}", componentId, status); + return Either.right(status); + } + + Either>, TitanOperationStatus> resourceInstancesRes = getAllComponentInstanceFromGraph(componentId, containerNodeType, true); + if (resourceInstancesRes.isRight()) { + TitanOperationStatus status = resourceInstancesRes.right().value(); + log.debug("Resource instance was found under component {}. status is {}", componentId, status); + return Either.right(status); + } + + List resourcesResult = new ArrayList(); + List requirementsResult = new ArrayList(); + + List> resourceInstances = resourceInstancesRes.left().value(); + if (resourceInstances != null && false == resourceInstances.isEmpty()) { + Map> compInstCapabilities = new HashMap>(); + Map> compInstReq = new HashMap>(); + Map> compInstArtifacts = new HashMap>(); + Map compInstOriginsMap = new HashMap(); + + for (ImmutablePair immutablePair : resourceInstances) { + + ComponentInstanceData resourceInstanceData = immutablePair.getKey(); + if (log.isDebugEnabled()) + log.debug("Going to fetch the relationships of resource instance {}", resourceInstanceData); + + ComponentInstance resourceInstance = new ComponentInstance(resourceInstanceData.getComponentInstDataDefinition()); + + TitanOperationStatus status = getFullComponentInstance(compInstCapabilities, compInstReq, compInstArtifacts, compInstOriginsMap, resourceInstance, compInstNodeType); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + resourcesResult.add(resourceInstance); + + Either>, TitanOperationStatus> relationshipsRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), + (String) resourceInstanceData.getUniqueId(), GraphEdgeLabels.RELATIONSHIP_INST, NodeTypeEnum.RelationshipInst, RelationshipInstData.class); + + if (relationshipsRes.isRight()) { + status = relationshipsRes.right().value(); + log.debug("After fetching all reslationships of resource instance {} under component {} . status is {}", resourceInstanceData.getUniqueId(), componentId, status); + if (status == TitanOperationStatus.NOT_FOUND) { + continue; + } else { + log.error("Failed to find relationhips of resource instance {} under component {}. status is {}", resourceInstanceData.getUniqueId(), componentId, status); + return Either.right(status); + } + } + + String sourceResourceUid = (String) resourceInstanceData.getUniqueId(); + + Map>> targetNodeToRelationship = new HashMap>>(); + + List> relationshipsImpl = relationshipsRes.left().value(); + status = populateTargetAndRelationsForGivenSource(targetNodeToRelationship, relationshipsImpl); + + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + if (targetNodeToRelationship.isEmpty()) { + log.error("No target found for relationship instances of resource instance {}", resourceInstanceData.getUniqueId()); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + + buildRelationsForSource(requirementsResult, sourceResourceUid, targetNodeToRelationship); + + } + + return Either.left(new ImmutablePair, List>(resourcesResult, requirementsResult)); + } else { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + } + + private Either, TitanOperationStatus> getRelationsForSource(String resourceInstanceUid) { + Either>, TitanOperationStatus> relationshipsRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceUid, + GraphEdgeLabels.RELATIONSHIP_INST, NodeTypeEnum.RelationshipInst, RelationshipInstData.class); + + TitanOperationStatus status; + List requirementsResult = new ArrayList(); + + if (relationshipsRes.isRight()) { + status = relationshipsRes.right().value(); + log.debug("After fetching all reslationships of resource instance {}. Status is {}", resourceInstanceUid, status); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.left(requirementsResult); + } else { + log.error("Failed to find relationhips of resource instance {}. Status is {}", resourceInstanceUid, status); + return Either.right(status); + } + } + + Map>> targetNodeToRelationship = new HashMap>>(); + + List> relationshipsImpl = relationshipsRes.left().value(); + status = populateTargetAndRelationsForGivenSource(targetNodeToRelationship, relationshipsImpl); + + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + if (targetNodeToRelationship.isEmpty()) { + log.error("No target found for relationship instances of resource instance {}", resourceInstanceUid); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + + buildRelationsForSource(requirementsResult, resourceInstanceUid, targetNodeToRelationship); + return Either.left(requirementsResult); + } + + private Either, TitanOperationStatus> getRelationsForTarget(String resourceInstanceUid) { + + TitanOperationStatus status; + + Either>, TitanOperationStatus> relationshipsRes = titanGenericDao.getParentNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceUid, + GraphEdgeLabels.CAPABILITY_NODE, NodeTypeEnum.RelationshipInst, RelationshipInstData.class); + + List requirementsResult = new ArrayList(); + + if (relationshipsRes.isRight()) { + status = relationshipsRes.right().value(); + log.debug("After fetching all reslationships of resource instance {}. Status is {}", resourceInstanceUid, status); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.left(requirementsResult); + } else { + log.error("Failed to find relationhips of resource instance {}. Status is {}", resourceInstanceUid, status); + return Either.right(status); + } + } + + Map>> sourceNodeToRelationship = new HashMap>>(); + + List> relationshipsImpl = relationshipsRes.left().value(); + status = populateSourceAndRelationsForGivenTarget(sourceNodeToRelationship, relationshipsImpl); + + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + if (sourceNodeToRelationship.isEmpty()) { + log.error("No target found for relationship instances of resource instance {}", resourceInstanceUid); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + + buildRelationsForTarget(requirementsResult, resourceInstanceUid, sourceNodeToRelationship); + return Either.left(requirementsResult); + } + + @Override + public Either getFullComponentInstance(ComponentInstance componentInstance, NodeTypeEnum compInstNodeType) { + Map> compInstCapabilities = new HashMap>(); + Map> compInstReq = new HashMap>(); + Map> compInstArtifacts = new HashMap>(); + Map compInstOrigins = new HashMap(); + + TitanOperationStatus fullResourceInstance = getFullComponentInstance(compInstCapabilities, compInstReq, compInstArtifacts, compInstOrigins, componentInstance, compInstNodeType); + if (!fullResourceInstance.equals(TitanOperationStatus.OK)) { + log.debug("failed to get full data of resource instance. error: {}", fullResourceInstance); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(fullResourceInstance)); + } + return Either.left(componentInstance); + } + + private TitanOperationStatus getFullComponentInstance(Map> compInstCapabilities, Map> compInstReq, + Map> compInstArtifacts, Map compInstOrigins, ComponentInstance compInst, NodeTypeEnum compInstNodeType) { + Component component = null; + ComponentOperation componentOperation = getComponentOperation(compInstNodeType); + String componentUid = compInst.getComponentUid(); + if (compInstOrigins.containsKey(componentUid)) { + component = compInstOrigins.get(componentUid); + } else { + Either metadataComponent = componentOperation.getMetadataComponent(componentUid, true); + if (metadataComponent.isRight()) { + log.debug("Failed to fetch the origin component for component instance, origin Id {}, error: {}", componentUid, metadataComponent.right().value()); + return TitanOperationStatus.GENERAL_ERROR; + } + component = metadataComponent.left().value(); + compInstOrigins.put(componentUid, component); + + } + String icon = component.getIcon(); + if (log.isDebugEnabled()) + log.debug("Fetch the resource instance icon from the resource itself. icon = {}", icon); + compInst.setIcon(icon); + String componentName = component.getName(); + compInst.setComponentName(componentName); + compInst.setComponentVersion(component.getVersion()); + if (component.getComponentType() == ComponentTypeEnum.RESOURCE) { + compInst.setToscaComponentName(((Resource) component).getToscaResourceName()); + } + + List componentInstances = new ArrayList<>(); + List derivedFromList = new ArrayList(); + + // For VFC/VL/CP + if (compInstNodeType == NodeTypeEnum.Resource && ((Resource) component).getResourceType() != ResourceTypeEnum.VF) { + resourceOperation.fillResourceDerivedListFromGraph(component.getUniqueId(), derivedFromList); + } else { + // Getting component instances that the origin component of this + // component instance is their container, so we can use the logic of + // getting req/cap from them + // and fill this component instance with those req/cap + Either>, TitanOperationStatus> allComponentInstanceFromGraph = getAllComponentInstanceFromGraph(componentUid, compInstNodeType, true); + if (allComponentInstanceFromGraph.isRight() && allComponentInstanceFromGraph.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Couldn't fetch component instances for component {} of type {}", componentUid, compInstNodeType); + return allComponentInstanceFromGraph.right().value(); + } + List> allCIs = allComponentInstanceFromGraph.isLeft() ? allComponentInstanceFromGraph.left().value() : new ArrayList<>(); + for (ImmutablePair entry : allCIs) { + componentInstances.add(new ComponentInstance(entry.left.getComponentInstDataDefinition())); + } + component.setComponentInstances(componentInstances); + } + + StorageOperationStatus capStatus = setCompInstCapabilitiesFromGraph(compInstCapabilities, component, compInstNodeType, compInst, derivedFromList); + if (capStatus != StorageOperationStatus.OK) { + log.debug("Failed to find capability of resource {}. status is {}", componentName, capStatus); + + } + capStatus = setCompInstRequirementsFromGraph(compInstReq, component, compInstNodeType, compInst); + if (capStatus != StorageOperationStatus.OK) { + log.debug("Failed to find requirements of resource {}. status is {}", componentName, capStatus); + + } + + capStatus = setCompInstDeploymentArtifactsFromGraph(compInstArtifacts, componentUid, compInst); + if (capStatus != StorageOperationStatus.OK) { + log.debug("Failed to find resource deployment artifacts of resource {}. status is {}", componentName, capStatus); + + } + + capStatus = setCompInstArtifactsFromGraph(compInst); + if (capStatus != StorageOperationStatus.OK) { + log.debug("Failed to find resource deployment artifacts of resource instance {} . status is {}", compInst.getName(), capStatus); + } + return TitanOperationStatus.OK; + } + + protected StorageOperationStatus setCompInstArtifactsFromGraph(ComponentInstance resourceInstance) { + + Map deploymentArtifacts = null; + if (resourceInstance.getDeploymentArtifacts() == null) { + deploymentArtifacts = new HashMap(); + } else { + deploymentArtifacts = new HashMap(resourceInstance.getDeploymentArtifacts()); + } + + Either, StorageOperationStatus> result = artifactOperation.getArtifacts(resourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, true, ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + if (result.isRight()) { + StorageOperationStatus status = result.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + return status; + } else { + resourceInstance.setDeploymentArtifacts(deploymentArtifacts); + return StorageOperationStatus.OK; + } + } + + Map artifacts = result.left().value(); + if ((artifacts != null) && !artifacts.isEmpty()) { + for (ArtifactDefinition artifact : artifacts.values()) { + if (artifact.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType())) { + Either, StorageOperationStatus> heatParamsForEnv = artifactOperation.getHeatParamsForEnv(artifact); + if (heatParamsForEnv.isRight()) { + log.debug("failed to get heat parameters values for heat artifact {}", artifact.getUniqueId()); + return heatParamsForEnv.right().value(); + } else { + artifact.setHeatParameters(heatParamsForEnv.left().value()); + } + } + } + + // add resource instance artifacts to the artifacts inherited from + // resource + deploymentArtifacts.putAll(artifacts); + resourceInstance.setDeploymentArtifacts(deploymentArtifacts); + } + + return StorageOperationStatus.OK; + + } + + // resourceInstance) { + // ArrayList(); + // heatEnvArtifact.getGeneratedFromId()); + // Either>, + // TitanOperationStatus> heatEnvValuesWithEdges = titanGenericDao + // !heatEnvValuesWithEdges.right().value().equals(TitanOperationStatus.NOT_FOUND)) + // { + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // heatEnvValuesWithEdges.left().value()){ + // pair.right.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + // heatValuesMap.get(parameter.getName()); + private Either>, TitanOperationStatus> getAllComponentInstanceFromGraph(String componentId, NodeTypeEnum containerNodeType, boolean withEdges) { + if (log.isDebugEnabled()) + log.debug("Going to fetch all resource instances nodes in graph associate to component {}", componentId); + Either>, TitanOperationStatus> resourceInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(containerNodeType), componentId, GraphEdgeLabels.RESOURCE_INST, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class, withEdges); + if (log.isDebugEnabled()) + log.debug("After fetching all component instances under component {}", componentId); + + if (resourceInstancesRes.isLeft()) { + printAllResourceInstancesNames(resourceInstancesRes); + } + return resourceInstancesRes; + } + + private void printAllResourceInstancesNames(Either>, TitanOperationStatus> resourceInstancesRes) { + if (log.isTraceEnabled()) { + StringBuilder builder = new StringBuilder(); + builder.append("Result is "); + List> listResData = resourceInstancesRes.left().value(); + for (ImmutablePair resInstPair : listResData) { + ComponentInstanceData resdata = resInstPair.getLeft(); + builder.append(resdata.getName()).append(", "); + } + log.trace(builder.toString()); + } + } + + private TitanOperationStatus populateTargetAndRelationsForGivenSource(Map>> targetNodeToRelationship, List> relationshipsImpl) { + if (relationshipsImpl != null && false == relationshipsImpl.isEmpty()) { + for (ImmutablePair pair : relationshipsImpl) { + RelationshipInstData relationshipInstData = pair.getKey(); + + GraphEdge requirementEdge = pair.getValue(); + String requirementName = (String) requirementEdge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + + Either, TitanOperationStatus> targetNodeRes = titanGenericDao.getChild(relationshipInstData.getUniqueIdKey(), relationshipInstData.getUniqueId(), GraphEdgeLabels.CAPABILITY_NODE, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + + if (targetNodeRes.isRight()) { + TitanOperationStatus status = targetNodeRes.right().value(); + log.error("Failed to find the target node of relationship inst {}. Status is {}", relationshipInstData, status); + return status; + } + + addRelationshipInstToTargetMap(targetNodeToRelationship, relationshipInstData, requirementName, targetNodeRes); + + } + } + + return TitanOperationStatus.OK; + } + + private TitanOperationStatus populateSourceAndRelationsForGivenTarget(Map>> sourceNodeToRelationship, List> relationshipsImpl) { + if (relationshipsImpl != null && false == relationshipsImpl.isEmpty()) { + for (ImmutablePair pair : relationshipsImpl) { + RelationshipInstData relationshipInstData = pair.getKey(); + + GraphEdge requirementEdge = pair.getValue(); + String requirementName = (String) requirementEdge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + + Either, TitanOperationStatus> sourceNodeRes = titanGenericDao.getParentNode(relationshipInstData.getUniqueIdKey(), relationshipInstData.getUniqueId(), GraphEdgeLabels.RELATIONSHIP_INST, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + + if (sourceNodeRes.isRight()) { + TitanOperationStatus status = sourceNodeRes.right().value(); + log.error("Failed to find the source node of relationship inst {}. Status is {}", relationshipInstData, status); + return status; + } + + addRelationshipInstToTargetMap(sourceNodeToRelationship, relationshipInstData, requirementName, sourceNodeRes); + + } + } + + return TitanOperationStatus.OK; + } + + private void buildRelationsForSource(List requirementsResult, String sourceResourceUid, Map>> targetNodeToRelationship) { + for (Entry>> targetToRel : targetNodeToRelationship.entrySet()) { + RequirementCapabilityRelDef requirementCapabilityRelDef = new RequirementCapabilityRelDef(); + requirementCapabilityRelDef.setFromNode(sourceResourceUid); + String targetUid = targetToRel.getKey(); + requirementCapabilityRelDef.setToNode(targetUid); + + List relationships = new ArrayList(); + + populateRelationships(targetToRel, relationships); + requirementCapabilityRelDef.setRelationships(relationships); + + requirementsResult.add(requirementCapabilityRelDef); + } + } + + private void buildRelationsForTarget(List requirementsResult, String targetResourceUid, Map>> sourceNodeToRelationship) { + for (Entry>> sourceToRel : sourceNodeToRelationship.entrySet()) { + RequirementCapabilityRelDef requirementCapabilityRelDef = new RequirementCapabilityRelDef(); + requirementCapabilityRelDef.setToNode(targetResourceUid); + String sourceUid = sourceToRel.getKey(); + requirementCapabilityRelDef.setFromNode(sourceUid); + + List relationships = new ArrayList(); + + populateRelationships(sourceToRel, relationships); + requirementCapabilityRelDef.setRelationships(relationships); + + requirementsResult.add(requirementCapabilityRelDef); + } + } + + private void addRelationshipInstToTargetMap(Map>> targetNodeToRelationship, RelationshipInstData relationshipInstData, String requirementName, + Either, TitanOperationStatus> targetNodeRes) { + + ImmutablePair targetResourcePair = targetNodeRes.left().value(); + ComponentInstanceData targetResourceData = targetResourcePair.getKey(); + + GraphEdge edge = targetResourcePair.right; + if (edge.getEdgeType().equals(GraphEdgeLabels.RELATIONSHIP_INST)) { + requirementName = (String) edge.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + } + + String targetResourceUid = (String) targetResourceData.getUniqueId(); + List> requirementRelationshipPair = targetNodeToRelationship.get(targetResourceUid); + if (requirementRelationshipPair == null) { + requirementRelationshipPair = new ArrayList>(); + targetNodeToRelationship.put(targetResourceUid, requirementRelationshipPair); + } + ImmutablePair reqRelationshipPair = new ImmutablePair(requirementName, relationshipInstData); + requirementRelationshipPair.add(reqRelationshipPair); + } + + private void populateRelationships(Entry>> targetToRel, List relationships) { + + List> values = targetToRel.getValue(); + for (ImmutablePair value : values) { + String reqName = value.getKey(); + RelationshipInstData relationshipInstData = value.getValue(); + RelationshipImpl relationshipImpl = new RelationshipImpl(); + relationshipImpl.setType(relationshipInstData.getType()); + RequirementAndRelationshipPair pair = new RequirementAndRelationshipPair(reqName, relationshipImpl); + pair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId()); + pair.setCapabilityUid(relationshipInstData.getCapabiltyId()); + pair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId()); + pair.setRequirementUid(relationshipInstData.getRequirementId()); + relationships.add(pair); + } + } + + /** + * FOR TEST ONLY + * + * @param resourceOperation + */ + public void setResourceOperation(ResourceOperation resourceOperation) { + this.resourceOperation = resourceOperation; + } + + @Override + public Either associateResourceInstances(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef relation, boolean inTransaction) { + + Either result = null; + try { + Either multiRequirements = associateResourceInstancesMultiRequirements(componentId, nodeType, relation); + if (multiRequirements.isRight()) { + TitanOperationStatus status = multiRequirements.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "associateComponentInstances"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("associateComponentInstances"); + log.debug("Failed to associate component instances. {}. Status is {}", relation, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + StorageOperationStatus updateCalculatedCapReqResult = updateCalculatedCapReq(relation, true); + if (!updateCalculatedCapReqResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "associateComponentInstances"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("associateComponentInstances"); + log.debug("Failed to associate component instances. {}. Status is {}", relation, updateCalculatedCapReqResult); + result = Either.right(updateCalculatedCapReqResult); + return result; + } + result = Either.left(multiRequirements.left().value()); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + } + + private Either associateResourceInstancesMultiRequirements(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef relation) { + + String fromNode = relation.getFromNode(); + String toNode = relation.getToNode(); + List relationships = relation.getRelationships(); + if (relationships == null || relationships.isEmpty()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedAddingResourceInstanceError, "AssociateResourceInstances - missing relationship", fromNode, componentId); + BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId); + log.debug("No requirement definition sent in order to set the relation between {} to {}", fromNode, toNode); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + + List relationshipsResult = new ArrayList(); + for (RequirementAndRelationshipPair immutablePair : relationships) { + String requirement = immutablePair.getRequirement(); + + Either associateRes = connectResourcesInService(componentId, nodeType, fromNode, toNode, immutablePair); + + if (associateRes.isRight()) { + TitanOperationStatus status = associateRes.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedAddingResourceInstanceError, "AssociateResourceInstances", fromNode, componentId); + BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId); + log.debug("Failed to associate resource instance {} to resource instnace {}. Status is {}", fromNode, toNode, status); + return Either.right(status); + } + + RelationshipInstData relationshipInstData = associateRes.left().value(); + RelationshipImpl relationshipImplResult = new RelationshipImpl(); + relationshipImplResult.setType(relationshipInstData.getType()); + RequirementAndRelationshipPair requirementAndRelationshipPair = new RequirementAndRelationshipPair(requirement, relationshipImplResult); + requirementAndRelationshipPair.setCapability(immutablePair.getCapability()); + requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId()); + requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId()); + requirementAndRelationshipPair.setCapabilityUid(immutablePair.getCapabilityUid()); + requirementAndRelationshipPair.setRequirementUid(immutablePair.getRequirementUid()); + relationshipsResult.add(requirementAndRelationshipPair); + + } + + RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef(); + capabilityRelDef.setFromNode(fromNode); + capabilityRelDef.setToNode(toNode); + capabilityRelDef.setRelationships(relationshipsResult); + + return Either.left(capabilityRelDef); + } + + @Override + public Either associateResourceInstances(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef relation) { + return associateResourceInstances(componentId, nodeType, relation, false); + } + + @Override + public Either, StorageOperationStatus> deleteAllComponentInstances(String containerComponentId, NodeTypeEnum containerNodeType, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + try { + Either, TitanOperationStatus> multiRequirements = deleteAllComponentInstancesInternal(containerComponentId, containerNodeType); + if (multiRequirements.isRight()) { + TitanOperationStatus status = multiRequirements.right().value(); + if (multiRequirements.right().value() != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "deleteAllResourceInstances - missing relationship"); + BeEcompErrorManager.getInstance().logBeSystemError("deleteAllResourceInstances - missing relationship"); + } + log.debug("Failed to delete resource instances of service {}. Status is {}", containerComponentId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + + result = Either.left(multiRequirements.left().value()); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + + } + + @Override + public Either, StorageOperationStatus> deleteAllComponentInstances(String containerComponentId, NodeTypeEnum nodeType) { + return deleteAllComponentInstances(containerComponentId, nodeType, false); + } + + public Either, TitanOperationStatus> deleteAllComponentInstancesInternal(String componentId, NodeTypeEnum nodeType) { + + log.debug("Going to delete all resource instances and their relatioships from service {}", componentId); + + Either>, TitanOperationStatus> resourceInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.RESOURCE_INST, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + + if (resourceInstancesRes.isRight()) { + TitanOperationStatus status = resourceInstancesRes.right().value(); + log.debug("After fetching all resource instances of service {}. Status is {}", componentId, status); + return Either.right(status); + } + + List result = new ArrayList(); + List> listOfResInstances = resourceInstancesRes.left().value(); + for (ImmutablePair resInstance : listOfResInstances) { + ComponentInstanceData resourceInstanceData = resInstance.getKey(); + String resourceInstUid = resourceInstanceData.getUniqueId(); + Either removeResourceInstanceRes = removeComponentInstanceFromComponent(nodeType, componentId, resourceInstUid); + log.debug("After removing resource instance {}. Result is {}", resourceInstUid, removeResourceInstanceRes); + if (removeResourceInstanceRes.isRight()) { + TitanOperationStatus status = removeResourceInstanceRes.right().value(); + log.error("After removing resource instance {}. Status is {}", resourceInstUid, status); + return Either.right(status); + } + ComponentInstance resourceInstance = removeResourceInstanceRes.left().value(); + result.add(resourceInstance); + } + + log.debug("The following resource instances was deleted from service {}:{}", componentId, result); + + return Either.left(result); + } + + public Either, Map>, StorageOperationStatus> cloneAllComponentInstancesFromContainerComponent(String componentIdFrom, Component component, NodeTypeEnum containerNodeType, + NodeTypeEnum compInstNodeType, LifecycleStateEnum targetLifecycle, Map> inputsValuesMap) { + + List list = new ArrayList(); + Map oldCompInstToNew = new HashMap<>(); + + ImmutablePair, Map> result = new ImmutablePair, Map>(list, oldCompInstToNew); + + Either, List>, StorageOperationStatus> allResourceInstances = getAllComponentInstances(componentIdFrom, containerNodeType, compInstNodeType, true); + + if (allResourceInstances.isRight()) { + StorageOperationStatus status = allResourceInstances.right().value(); + if (status.equals(StorageOperationStatus.NOT_FOUND)) { + + return Either.left(result); + } else { + log.error("failed to get all resource instances for service {}. status={}", componentIdFrom, status); + return Either.right(status); + } + } + + List riList = allResourceInstances.left().value().left; + Map riMapper = new HashMap<>(); + int instanceNumber = 0; + for (ComponentInstance ri : riList) { + instanceNumber++; + String origRiUniqueID = ri.getUniqueId(); + Either createResourceInstance = createComponentInstance(component.getUniqueId(), containerNodeType, String.valueOf(instanceNumber), false, ri, compInstNodeType, true, true); + if (createResourceInstance.isRight()) { + StorageOperationStatus status = createResourceInstance.right().value(); + log.error("failed to clone resource instance {}. status ={}", origRiUniqueID, status); + return Either.right(status); + } + ComponentInstance createdInstance = createResourceInstance.left().value(); + riMapper.put(origRiUniqueID, createdInstance); + StorageOperationStatus associateArtifactsToResource = cloneResourceInstanceArtifacts(createdInstance, ri, targetLifecycle); + if (associateArtifactsToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} artifacts. error {} ", ri.getNormalizedName(), associateArtifactsToResource.name()); + return Either.right(associateArtifactsToResource); + } + + StorageOperationStatus associatePropertyValuesToResource = cloneResourceInstancePropertyValues(createdInstance, ri); + if (associatePropertyValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} property values. error {} ", ri.getNormalizedName(), associatePropertyValuesToResource.name()); + return Either.right(associatePropertyValuesToResource); + } + + StorageOperationStatus associateAttributeValuesToResource = cloneResourceInstanceAttributeValues(createdInstance, ri); + if (associateAttributeValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} attribute values. error {} ", ri.getNormalizedName(), associateAttributeValuesToResource.name()); + return Either.right(associateAttributeValuesToResource); + } + + StorageOperationStatus associateInputValuesToResource = cloneResourceInstanceInputsValues(createdInstance, ri, component, inputsValuesMap); + if (associateInputValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} property values. error {} ", ri.getNormalizedName(), associatePropertyValuesToResource.name()); + return Either.right(associatePropertyValuesToResource); + } + + list.add(createdInstance); + oldCompInstToNew.put(origRiUniqueID, createdInstance.getUniqueId()); + } + + List relationsList = allResourceInstances.left().value().right; + for (RequirementCapabilityRelDef relation : relationsList) { + String origFrom = relation.getFromNode(); + String origTo = relation.getToNode(); + relation.setFromNode(riMapper.get(origFrom).getUniqueId()); + relation.setToNode(riMapper.get(origTo).getUniqueId()); + List relationships = relation.getRelationships(); + for (RequirementAndRelationshipPair pair : relationships) { + // for all atomic resource instances need to update to relevant + // new ri ids + String capOwnerId = pair.getCapabilityOwnerId(); + String reqOwnerId = pair.getRequirementOwnerId(); + if (isAtomicComponentInstance(riMapper.get(origFrom))) { + reqOwnerId = riMapper.get(reqOwnerId).getUniqueId(); + } + if (isAtomicComponentInstance(riMapper.get(origTo))) { + capOwnerId = riMapper.get(capOwnerId).getUniqueId(); + } + pair.setRequirementOwnerId(reqOwnerId); + pair.setCapabilityOwnerId(capOwnerId); + } + + Either associateInstances = associateResourceInstances(component.getUniqueId(), containerNodeType, relation, true); + if (associateInstances.isRight()) { + StorageOperationStatus status = associateInstances.right().value(); + log.error("failed to assosiate resource instance {} and resource instance {}. status ={}", relation.getFromNode(), relation.getToNode(), status); + return Either.right(status); + } + } + + return Either.left(result); + } + + public Either, Map>, StorageOperationStatus> cloneAllComponentInstancesFromContainerComponent(String componentIdFrom, String componentIdTo, NodeTypeEnum containerNodeType, + NodeTypeEnum compInstNodeType, LifecycleStateEnum targetLifecycle, TitanVertex metadataVertex, Resource prevResource, Resource newResource, Map> inputsPropMap) { + + List list = new ArrayList(); + Map oldCompInstToNew = new HashMap<>(); + + ImmutablePair, Map> result = new ImmutablePair, Map>(list, oldCompInstToNew); + + // Either, + // List>, StorageOperationStatus> + // allResourceInstances = getAllComponentInstances(componentIdFrom, + // containerNodeType, compInstNodeType, true); + // + // + // if (allResourceInstances.isRight()) { + // StorageOperationStatus status = allResourceInstances.right().value(); + // if (status.equals(StorageOperationStatus.NOT_FOUND)) { + // + // return Either.left(result); + // } else { + // log.error("failed to get all resource instances for service {}. + // status={}", componentIdFrom, status); + // return Either.right(status); + // } + // } + + // ImmutablePair, + // List> instanceRelationPair = + // allResourceInstances.left().value(); + + // ImmutablePair, + // List> instanceRelationPair = new + // ImmutablePair, + // List>(prevResource.getComponentInstances(), + // prevResource.getComponentInstancesRelations()); + List riList = prevResource.getComponentInstances(); + Map riMapper = new HashMap<>(); + int instanceNumber = 0; + long timeProperties = 0; + if (riList != null) { + for (ComponentInstance ri : riList) { + instanceNumber++; + String origRiUniqueID = ri.getUniqueId(); + Either createResourceInstance = createComponentInstance(componentIdTo, containerNodeType, String.valueOf(instanceNumber), false, ri, compInstNodeType, true, true, metadataVertex); + if (createResourceInstance.isRight()) { + StorageOperationStatus status = createResourceInstance.right().value(); + log.error("failed to clone resource instance {}. status ={}", origRiUniqueID, status); + return Either.right(status); + } + TitanVertex createdInstance = createResourceInstance.left().value(); + String createdInstanceId = (String) titanGenericDao.getProperty(createdInstance, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + StorageOperationStatus associateArtifactsToResource = cloneResourceInstanceArtifacts(createdInstance, ri, targetLifecycle); + if (associateArtifactsToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} artifacts. error {} ", ri.getNormalizedName(), associateArtifactsToResource.name()); + return Either.right(associateArtifactsToResource); + } + + long start = System.currentTimeMillis(); + StorageOperationStatus associatePropertyValuesToResource = cloneResourceInstancePropertyValues(createdInstance, ri, inputsPropMap, newResource); + if (associatePropertyValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} property values. error {} ", ri.getNormalizedName(), associatePropertyValuesToResource.name()); + return Either.right(associatePropertyValuesToResource); + } + long end = System.currentTimeMillis(); + timeProperties += (end - start); + + StorageOperationStatus associateAttributeValuesToResource = cloneResourceInstanceAttributeValues(createdInstance, ri, createdInstanceId); + if (associateAttributeValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} attribute values. error {} ", ri.getNormalizedName(), associateAttributeValuesToResource.name()); + return Either.right(associateAttributeValuesToResource); + } + + StorageOperationStatus associateInputValuesToResource = cloneResourceInstanceInputsValues(createdInstance, ri, createdInstanceId, newResource, null); + if (associateInputValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} property values. error {} ", ri.getNormalizedName(), associatePropertyValuesToResource.name()); + return Either.right(associatePropertyValuesToResource); + } + Map properties = titanGenericDao.getProperties(createdInstance); + ComponentInstanceData createdComponentInstance = GraphElementFactory.createElement(NodeTypeEnum.ResourceInstance.getName(), GraphElementTypeEnum.Node, properties, ComponentInstanceData.class); + ComponentInstance createdResourceInstance = new ComponentInstance(createdComponentInstance.getComponentInstDataDefinition()); + riMapper.put(origRiUniqueID, createdResourceInstance); + + list.add(createdResourceInstance); + oldCompInstToNew.put(origRiUniqueID, createdResourceInstance.getUniqueId()); + } + } + log.info("*********** total properties in ms {}", timeProperties); + + // List relationsList = + // instanceRelationPair.right; + List relationsList = prevResource.getComponentInstancesRelations(); + if (relationsList != null) { + for (RequirementCapabilityRelDef relation : relationsList) { + String origFrom = relation.getFromNode(); + String origTo = relation.getToNode(); + relation.setFromNode(riMapper.get(origFrom).getUniqueId()); + relation.setToNode(riMapper.get(origTo).getUniqueId()); + List relationships = relation.getRelationships(); + for (RequirementAndRelationshipPair pair : relationships) { + // for all atomic resource instances need to update to + // relevant + // new ri ids + String capOwnerId = pair.getCapabilityOwnerId(); + String reqOwnerId = pair.getRequirementOwnerId(); + if (isAtomicComponentInstance(riMapper.get(origFrom))) { + reqOwnerId = riMapper.get(reqOwnerId).getUniqueId(); + } + if (isAtomicComponentInstance(riMapper.get(origTo))) { + capOwnerId = riMapper.get(capOwnerId).getUniqueId(); + } + pair.setRequirementOwnerId(reqOwnerId); + pair.setCapabilityOwnerId(capOwnerId); + } + + Either associateInstances = associateResourceInstances(componentIdTo, containerNodeType, relation, true); + if (associateInstances.isRight()) { + StorageOperationStatus status = associateInstances.right().value(); + log.error("failed to assosiate resource instance {} and resource instance {}. status ={}", relation.getFromNode(), relation.getToNode(), status); + return Either.right(status); + } + } + } + return Either.left(result); + } + + private boolean isAtomicComponentInstance(ComponentInstance componentInstance) { + OriginTypeEnum originType = componentInstance.getOriginType(); + if (originType.equals(OriginTypeEnum.VFC) || originType.equals(OriginTypeEnum.VL) || originType.equals(OriginTypeEnum.CP)) { + return true; + } + return false; + } + + private StorageOperationStatus cloneResourceInstanceArtifacts(ComponentInstance toResourceInstance, ComponentInstance fromResourceInstance, LifecycleStateEnum targetLifecycle) { + + Either, StorageOperationStatus> getArtifactsOfRI = artifactOperation.getArtifacts(fromResourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, true); + if (getArtifactsOfRI.isRight()) { + StorageOperationStatus status = getArtifactsOfRI.right().value(); + if (status.equals(StorageOperationStatus.NOT_FOUND)) { + status = StorageOperationStatus.OK; + } + return status; + } + + Map artifacts = getArtifactsOfRI.left().value(); + for (Entry entry : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + // US687135 Do not Add VF_MODULES_METADATA when checking out + if (ArtifactTypeEnum.VF_MODULES_METADATA.getType().equals(artifactDefinition.getArtifactType())) { + // The artifact of type VF_MODULES_METADATA should not be cloned + // unless we are changing the state to certified. + if (targetLifecycle != null && targetLifecycle != LifecycleStateEnum.CERTIFIED) { + continue; + } + } + Either addArifactToResource = Either.left(artifactDefinition); + + addArifactToResource = artifactOperation.addArifactToComponent(artifactDefinition, toResourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, false, true); + + if (addArifactToResource.isRight()) { + return addArifactToResource.right().value(); + } + } + toResourceInstance.setDeploymentArtifacts(artifacts); + return StorageOperationStatus.OK; + } + + private StorageOperationStatus cloneResourceInstanceArtifacts(TitanVertex toResourceInstance, ComponentInstance fromResourceInstance, LifecycleStateEnum targetLifecycle) { + + Either, StorageOperationStatus> getArtifactsOfRI = artifactOperation.getArtifactsVertecies(fromResourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, true); + if (getArtifactsOfRI.isRight()) { + StorageOperationStatus status = getArtifactsOfRI.right().value(); + if (status.equals(StorageOperationStatus.NOT_FOUND)) { + status = StorageOperationStatus.OK; + } + return status; + } + + Map artifacts = getArtifactsOfRI.left().value(); + for (Entry entry : artifacts.entrySet()) { + + TitanVertex artifactVertex = entry.getValue(); + // US687135 Do not Add VF_MODULES_METADATA when checking out + String artifactType = (String) titanGenericDao.getProperty(artifactVertex, GraphPropertiesDictionary.ARTIFACT_TYPE.getProperty()); + String label = (String) titanGenericDao.getProperty(artifactVertex, GraphPropertiesDictionary.ARTIFACT_LABEL.getProperty()); + if (ArtifactTypeEnum.VF_MODULES_METADATA.getType().equals(artifactType)) { + // The artifact of type VF_MODULES_METADATA should not be cloned + // unless we are changing the state to certified. + if (targetLifecycle != null && targetLifecycle != LifecycleStateEnum.CERTIFIED) { + continue; + } + } + + StorageOperationStatus addArifactToResource = artifactOperation.addArifactToComponent(artifactVertex, toResourceInstance, label); + + if (!addArifactToResource.equals(StorageOperationStatus.OK)) { + return addArifactToResource; + } + } + // toResourceInstance.setDeploymentArtifacts(artifacts); + return StorageOperationStatus.OK; + } + + public Either increaseAndGetResourceInstanceSpecificCounter(String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction) { + + Either result = null; + try { + + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + Either vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId); + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of resource instance for id = {}", resourceInstanceId); + TitanOperationStatus status = vertexService.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value())); + return result; + } + Vertex vertex = vertexService.left().value(); + + VertexProperty vertexProperty = vertex.property(counterType.getProperty()); + Integer counter = 0; + if (vertexProperty.isPresent()) { + if (vertexProperty.value() != null) { + counter = (Integer) vertexProperty.value(); + } + } + + counter++; + vertex.property(counterType.getProperty(), counter); + + result = Either.left(counter); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either increaseAndGetResourceInstanceSpecificCounter(TitanVertex resourceInstanceVertex, GraphPropertiesDictionary counterType) { + + Either result = null; + + VertexProperty vertexProperty = resourceInstanceVertex.property(counterType.getProperty()); + Integer counter = 0; + if (vertexProperty.isPresent()) { + if (vertexProperty.value() != null) { + counter = (Integer) vertexProperty.value(); + } + } + counter++; + resourceInstanceVertex.property(counterType.getProperty(), counter); + + result = Either.left(counter); + return result; + + } + + @Override + public Either, StorageOperationStatus> getAllComponentInstancesNames(String serviceId, NodeTypeEnum nodeType, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + try { + + Either, TitanOperationStatus> resInstancesOfService = getComponentInstancesNameOfService(serviceId, nodeType); + + log.debug("After fetching resource instances of service {}. Result is {}", serviceId, resInstancesOfService); + if (resInstancesOfService.isRight()) { + TitanOperationStatus status = resInstancesOfService.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find resource instances of service {}. Status is {}", serviceId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List names = resInstancesOfService.left().value(); + + if (names == null || names.isEmpty()) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + result = Either.left(names); + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + return result; + } + + private Either, TitanOperationStatus> getComponentInstancesNameOfService(String serviceId, NodeTypeEnum nodeType) { + + List resourcesInstanseName = new ArrayList(); + Either>, TitanOperationStatus> resourceInstancesRes = getAllComponentInstanceFromGraph(serviceId, nodeType, false); + if (resourceInstancesRes.isRight()) { + TitanOperationStatus status = resourceInstancesRes.right().value(); + log.debug("Resource instance was found under service {}. Status is {}", serviceId, status); + return Either.right(status); + } + + List> resourceInstances = resourceInstancesRes.left().value(); + if (resourceInstances != null && false == resourceInstances.isEmpty()) { + + for (ImmutablePair immutablePair : resourceInstances) { + ComponentInstanceData resourceInstanceData = immutablePair.getKey(); + log.debug("Going to fetch the relationships of resource instance {}", resourceInstanceData); + resourcesInstanseName.add(resourceInstanceData.getComponentInstDataDefinition().getName()); + + } + } + + return Either.left(resourcesInstanseName); + } + + @Override + public Either, StorageOperationStatus> getAllComponentInstancesNames(String componentId, NodeTypeEnum nodeType) { + + return getAllComponentInstancesNames(componentId, nodeType, false); + } + + @Override + public Either getResourceInstanceById(String resourceId) { + Either resourceInstanceData = findResourceInstance(resourceId); + + if (resourceInstanceData.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceInstanceData.right().value())); + } + + return Either.left(new ComponentInstance(resourceInstanceData.left().value().getComponentInstDataDefinition())); + + } + + private StorageOperationStatus setCompInstDeploymentArtifactsFromGraph(Map> resourcesArtifacts, String uniqueId, ComponentInstance resourceInstance) { + + if (resourcesArtifacts.containsKey(uniqueId)) { + resourceInstance.setDeploymentArtifacts(resourcesArtifacts.get(uniqueId)); + return StorageOperationStatus.OK; + } + + Either, StorageOperationStatus> result = artifactOperation.getArtifacts(uniqueId, NodeTypeEnum.Resource, true, ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + if (result.isRight()) { + StorageOperationStatus status = result.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + return status; + } else { + return StorageOperationStatus.OK; + } + } + Map artifacts = result.left().value(); + if (!artifacts.isEmpty()) { + Map tempArtifacts = new HashMap(artifacts); + for (Entry artifact : artifacts.entrySet()) { + if (!artifact.getValue().checkEsIdExist()) { + tempArtifacts.remove(artifact.getKey()); + } + } + resourceInstance.setDeploymentArtifacts(tempArtifacts); + resourcesArtifacts.put(uniqueId, tempArtifacts); + } + + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus setCompInstCapabilitiesFromGraph(Map> resourcesCapabilities, Component component, NodeTypeEnum compInstType, ComponentInstance resourceInstance, + List respourceDerivedList) { + + StorageOperationStatus status; + ComponentOperation componentOperation = getComponentOperation(compInstType); + Either>, TitanOperationStatus> eitherCapabilities = componentOperation.getCapabilities(component, compInstType, true); + if (eitherCapabilities.isLeft()) { + status = StorageOperationStatus.OK; + Map> capabilities = eitherCapabilities.left().value(); + if (capabilities != null && !capabilities.isEmpty()) { + capabilities.forEach((type, list) -> { + if (list != null && !list.isEmpty()) { + list.forEach((capability) -> { + // We want to set ownerId only for instances coming + // from atomic resources, otherwise we don't want + // to overwrite the existing ownerId of underlying + // component instances + if (isAtomicResource(component)) { + capability.setOwnerId(resourceInstance.getUniqueId()); + capability.setOwnerName(resourceInstance.getName()); + capability.setCapabilitySources(respourceDerivedList); + } + }); + } + }); + resourceInstance.setCapabilities(capabilities); + } + } else { + status = StorageOperationStatus.GENERAL_ERROR; + } + return status; + + } + + private StorageOperationStatus setCompInstRequirementsFromGraph(Map> resourcesReq, Component component, NodeTypeEnum compInstType, ComponentInstance resourceInstance) { + StorageOperationStatus status; + ComponentOperation componentOperation = getComponentOperation(compInstType); + Either>, TitanOperationStatus> eitherCapabilities = componentOperation.getRequirements(component, compInstType, true); + if (eitherCapabilities.isLeft()) { + status = StorageOperationStatus.OK; + Map> requirements = eitherCapabilities.left().value(); + if (requirements != null && !requirements.isEmpty()) { + // We want to set ownerId only for instances coming from atomic + // resources, otherwise we don't want + // to overwrite the existing ownerId of underlying component + // instances + if (isAtomicResource(component)) { + requirements.forEach((type, list) -> { + if (list != null && !list.isEmpty()) { + list.forEach((requirement) -> { + requirement.setOwnerId(resourceInstance.getUniqueId()); + requirement.setOwnerName(resourceInstance.getName()); + }); + } + }); + } + resourceInstance.setRequirements(requirements); + } + } else { + status = StorageOperationStatus.GENERAL_ERROR; + } + return status; + } + + public Either>, TitanOperationStatus> getCapabilities(ComponentInstance compInstance, NodeTypeEnum nodeTypeEnum) { + + DataNodeCollector collector = () -> titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeTypeEnum), compInstance.getUniqueId(), GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, + CapabilityData.class); + + return getDataFromGraph(collector); + + } + + public Either>, TitanOperationStatus> getRequirements(ComponentInstance compInstance, NodeTypeEnum nodeTypeEnum) { + + DataNodeCollector collector = () -> titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeTypeEnum), compInstance.getUniqueId(), GraphEdgeLabels.CALCULATED_REQUIREMENT, NodeTypeEnum.Requirement, + RequirementData.class); + + return getDataFromGraph(collector); + + } + + public Either isAvailableRequirement(ComponentInstance fromResInstance, RequirementAndRelationshipPair relationPair) { + Either fromRi = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), fromResInstance.getUniqueId()); + if (fromRi.isRight()) { + log.debug("Failed to fetch component instance {} error {}", fromResInstance.getUniqueId(), fromRi.right().value()); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Iterator edgeIter = fromRi.left().value().edges(Direction.OUT, GraphEdgeLabels.CALCULATED_REQUIREMENT.name()); + if (edgeIter == null || !edgeIter.hasNext()) { + log.debug("No available CALCULATED_REQUIREMENT edges. All full filled for RI {}", fromResInstance.getUniqueId()); + return Either.left(false); + } + boolean exist = false; + while (edgeIter.hasNext()) { + Edge edge = edgeIter.next(); + TitanVertex reqVertex = (TitanVertex) edge.inVertex(); + String reqId = (String) titanGenericDao.getProperty(reqVertex, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement)); + if (reqId.equals(relationPair.getRequirementUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(relationPair.getRequirementOwnerId())) { + String leftOccurrences = (String) edge.value(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null && !leftOccurrences.equals(RequirementData.MAX_OCCURRENCES)) { + Integer leftIntValue = Integer.parseInt(leftOccurrences); + if (leftIntValue > 0) { + exist = true; + } + } else { + exist = true; + } + break; + } + } + } + return Either.left(exist); + } + + public Either isAvailableCapabilty(ComponentInstance toResInstance, RequirementAndRelationshipPair relationPair) { + Either fromRi = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), toResInstance.getUniqueId()); + if (fromRi.isRight()) { + log.debug("Failed to fetch component instance {}. Error: {}", toResInstance.getUniqueId(), fromRi.right().value()); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Iterator edgeIter = fromRi.left().value().edges(Direction.OUT, GraphEdgeLabels.CALCULATED_CAPABILITY.name()); + if (edgeIter == null || !edgeIter.hasNext()) { + log.debug("No available CALCULATED_CAPABILITY edges. All full filled for RI {}", toResInstance.getUniqueId()); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + boolean exist = false; + while (edgeIter.hasNext()) { + Edge edge = edgeIter.next(); + TitanVertex reqVertex = (TitanVertex) edge.inVertex(); + String capId = (String) titanGenericDao.getProperty(reqVertex, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability)); + if (capId.equals(relationPair.getCapabilityUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(relationPair.getCapabilityOwnerId())) { + String leftOccurrences = (String) edge.value(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null && !leftOccurrences.equals(CapabilityData.MAX_OCCURRENCES)) { + Integer leftIntValue = Integer.parseInt(leftOccurrences); + if (leftIntValue > 0) { + exist = true; + } + } else { + exist = true; + } + break; + } + } + } + return Either.left(exist); + } + + interface DataNodeCollector { + Either>, TitanOperationStatus> getDataNodes(); + } + + public Either>, TitanOperationStatus> getDataFromGraph(DataNodeCollector dataCollector) { + Either>, TitanOperationStatus> eitherRet; + + Either>, TitanOperationStatus> childrenNodes = dataCollector.getDataNodes(); + + if (childrenNodes.isLeft()) { + List> collectedData = childrenNodes.left().value().stream().map(element -> new ImmutablePair(element.getLeft(), element.getRight())).collect(Collectors.toList()); + eitherRet = Either.left(collectedData); + } else { + eitherRet = Either.right(childrenNodes.right().value()); + } + return eitherRet; + } + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType) { + if (NodeTypeEnum.Service == componentType) { + return serviceOperation; + } else if (NodeTypeEnum.Resource == componentType) { + return resourceOperation; + } + return null; + } + + private boolean isAtomicResource(Component component) { + // true if component is of type VL/CP/VFC + boolean isFromAtomicResource = (component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() != ResourceTypeEnum.VF); + return isFromAtomicResource; + } + + private StorageOperationStatus cloneResourceInstanceAttributeValues(ComponentInstance createdInstance, ComponentInstance resourceInstance) { + Wrapper storageStatusWrapper = new Wrapper<>(); + Wrapper> compInstanceAttList = new Wrapper<>(); + + findAllAttributesOfResourceInstance(resourceInstance, compInstanceAttList, storageStatusWrapper); + + if (storageStatusWrapper.isEmpty()) { + validateListNotEmpty(storageStatusWrapper, compInstanceAttList.getInnerElement()); + } + + if (storageStatusWrapper.isEmpty()) { + List attributesOnInstance = compInstanceAttList.getInnerElement(); + for (int i = 0; i < attributesOnInstance.size() && storageStatusWrapper.isEmpty(); i++) { + cloneSingleAttributeOnResourceInstance(createdInstance, attributesOnInstance.get(i), storageStatusWrapper); + } + } + + StorageOperationStatus result = storageStatusWrapper.isEmpty() ? StorageOperationStatus.OK : storageStatusWrapper.getInnerElement(); + return result; + + } + + private StorageOperationStatus cloneResourceInstanceAttributeValues(TitanVertex createdInstanceVertex, ComponentInstance resourceInstance, String instanceId) { + Wrapper storageStatusWrapper = new Wrapper<>(); + Wrapper> compInstanceAttList = new Wrapper<>(); + + findAllAttributesOfResourceInstance(resourceInstance, compInstanceAttList, storageStatusWrapper); + + if (storageStatusWrapper.isEmpty()) { + validateListNotEmpty(storageStatusWrapper, compInstanceAttList.getInnerElement()); + } + + if (storageStatusWrapper.isEmpty()) { + List attributesOnInstance = compInstanceAttList.getInnerElement(); + for (int i = 0; i < attributesOnInstance.size() && storageStatusWrapper.isEmpty(); i++) { + StorageOperationStatus result = cloneSingleAttributeOnResourceInstance(createdInstanceVertex, attributesOnInstance.get(i), instanceId); + if (!result.equals(StorageOperationStatus.OK)) { + log.trace("Failed to clone attribute for instance {} error {}", instanceId, result); + return result; + } + } + } + + StorageOperationStatus result = storageStatusWrapper.isEmpty() ? StorageOperationStatus.OK : storageStatusWrapper.getInnerElement(); + return result; + + } + + private void validateListNotEmpty(Wrapper storageStatusWrapper, List attributesOnInstance) { + if (attributesOnInstance == null || attributesOnInstance.isEmpty() == true) { + storageStatusWrapper.setInnerElement(StorageOperationStatus.OK); + } + } + + private void findAllAttributesOfResourceInstance(ComponentInstance resourceInstance, Wrapper> compInstanceAttList, Wrapper storageStatusWrapper) { + + Either, TitanOperationStatus> allAttributes = attributeOperation.getAllAttributesOfResourceInstance(resourceInstance); + if (allAttributes.isRight()) { + TitanOperationStatus status = allAttributes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + storageStatusWrapper.setInnerElement(storageStatus); + } else { + compInstanceAttList.setInnerElement(allAttributes.left().value()); + } + } + + private void cloneSingleAttributeOnResourceInstance(ComponentInstance createdInstance, ComponentInstanceAttribute attribute, Wrapper storageStatusWrapper) { + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (attribute.getValueUniqueUid() != null) { + attribute.setValueUniqueUid(null); + Either counterRes = increaseAndGetResourceInstanceSpecificCounter(createdInstance.getUniqueId(), GraphPropertiesDictionary.ATTRIBUTE_COUNTER, true); + if (counterRes.isRight()) { + storageStatusWrapper.setInnerElement(counterRes.right().value()); + } else { + Either addAttributeToResourceInstance = addAttributeToResourceInstance(attribute, createdInstance.getUniqueId(), counterRes.left().value()); + + if (addAttributeToResourceInstance.isRight()) { + TitanOperationStatus status = addAttributeToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + storageStatusWrapper.setInnerElement(storageStatus); + } + } + } + + } + + private StorageOperationStatus cloneSingleAttributeOnResourceInstance(TitanVertex createdInstanceVertex, ComponentInstanceAttribute attribute, String instanceId) { + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (attribute.getValueUniqueUid() != null) { + attribute.setValueUniqueUid(null); + Either counterRes = increaseAndGetResourceInstanceSpecificCounter(createdInstanceVertex, GraphPropertiesDictionary.ATTRIBUTE_COUNTER); + if (counterRes.isRight()) { + return counterRes.right().value(); + } else { + Either addAttributeToResourceInstance = addAttributeToResourceInstance(attribute, instanceId, counterRes.left().value()); + + if (addAttributeToResourceInstance.isRight()) { + TitanOperationStatus status = addAttributeToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + } + } + return StorageOperationStatus.OK; + + } + + private void connectAttValueDataToComponentInstanceData(Wrapper errorWrapper, ComponentInstanceData compIns, AttributeValueData attValueData) { + + Either createRelResult = titanGenericDao.createRelation(compIns, attValueData, GraphEdgeLabels.ATTRIBUTE_VALUE, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + errorWrapper.setInnerElement(operationStatus); + BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToComponentInstanceData", + "Failed to associate resource instance " + compIns.getUniqueId() + " attribute value " + attValueData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR); + } + } + + private void connectInputValueDataToComponentInstanceData(Wrapper errorWrapper, ComponentInstanceData compIns, InputValueData attValueData) { + + Either createRelResult = titanGenericDao.createRelation(compIns, attValueData, GraphEdgeLabels.INPUT_VALUE, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + errorWrapper.setInnerElement(operationStatus); + BeEcompErrorManager.getInstance().logInternalFlowError("connectInputValueDataToComponentInstanceData", + "Failed to associate resource instance " + compIns.getUniqueId() + " input value " + attValueData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR); + } + } + + private void connectAttValueDataToAttData(Wrapper errorWrapper, AttributeData attData, AttributeValueData attValueData) { + + Either createRelResult = titanGenericDao.createRelation(attValueData, attData, GraphEdgeLabels.ATTRIBUTE_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToAttData", + "Failed to associate attribute value " + attValueData.getUniqueId() + " to attribute " + attData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR); + + errorWrapper.setInnerElement(operationStatus); + } + } + + private void connectInputValueDataToInputData(Wrapper errorWrapper, InputsData attData, InputValueData attValueData) { + + Either createRelResult = titanGenericDao.createRelation(attValueData, attData, GraphEdgeLabels.INPUT_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("connectInputValueDataToInputData", "Failed to associate input value " + attValueData.getUniqueId() + " to input " + attData.getUniqueId() + " in graph. status is " + operationStatus, + ErrorSeverity.ERROR); + + errorWrapper.setInnerElement(operationStatus); + } + } + + private void createAttributeValueDataNode(ComponentInstanceAttribute attributeInstanceProperty, Integer index, Wrapper errorWrapper, ComponentInstanceData resourceInstanceData, + Wrapper attValueDataWrapper) { + String valueUniqueUid = attributeInstanceProperty.getValueUniqueUid(); + if (valueUniqueUid == null) { + + String attValueDatauniqueId = UniqueIdBuilder.buildResourceInstanceAttributeValueUid(resourceInstanceData.getUniqueId(), index); + AttributeValueData attributeValueData = buildAttributeValueDataFromComponentInstanceAttribute(attributeInstanceProperty, attValueDatauniqueId); + + log.debug("Before adding attribute value to graph {}", attributeValueData); + Either createNodeResult = titanGenericDao.createNode(attributeValueData, AttributeValueData.class); + log.debug("After adding attribute value to graph {}", attributeValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + errorWrapper.setInnerElement(operationStatus); + } else { + attValueDataWrapper.setInnerElement(createNodeResult.left().value()); + } + + } else { + BeEcompErrorManager.getInstance().logInternalFlowError("CreateAttributeValueDataNode", "attribute value already exists.", ErrorSeverity.ERROR); + errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST); + } + } + + /* + * private void createInputValueDataNode(ComponentInstanceInput inputInstanceProperty, Integer index, Wrapper errorWrapper, ComponentInstanceData resourceInstanceData, Wrapper attValueDataWrapper) { + * String valueUniqueUid = inputInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { + * + * String attValueDatauniqueId = UniqueIdBuilder.buildResourceInstanceInputValueUid(resourceInstanceData. getUniqueId(), index); AttributeValueData attributeValueData = buildAttributeValueDataFromComponentInstanceAttribute( inputInstanceProperty, + * attValueDatauniqueId); + * + * log.debug("Before adding attribute value to graph {}", attributeValueData); Either createNodeResult = titanGenericDao.createNode(attributeValueData, AttributeValueData.class); + * log.debug("After adding attribute value to graph {}", attributeValueData); + * + * if (createNodeResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right().value(); errorWrapper.setInnerElement(operationStatus); } else { attValueDataWrapper.setInnerElement(createNodeResult.left().value()); } + * + * } else { BeEcompErrorManager.getInstance().logInternalFlowError( "CreateAttributeValueDataNode", "attribute value already exists.", ErrorSeverity.ERROR); errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST); } } + */ + + private AttributeValueData buildAttributeValueDataFromComponentInstanceAttribute(ComponentInstanceAttribute resourceInstanceAttribute, String uniqueId) { + AttributeValueData attributeValueData = new AttributeValueData(); + attributeValueData.setUniqueId(uniqueId); + attributeValueData.setHidden(resourceInstanceAttribute.isHidden()); + attributeValueData.setValue(resourceInstanceAttribute.getValue()); + attributeValueData.setType(resourceInstanceAttribute.getType()); + long currentTimeMillis = System.currentTimeMillis(); + attributeValueData.setCreationTime(currentTimeMillis); + attributeValueData.setModificationTime(currentTimeMillis); + return attributeValueData; + } + + private InputValueData buildAttributeValueDataFromComponentInstanceAttribute(ComponentInstanceInput resourceInstanceInput, String uniqueId) { + InputValueData inputValueData = new InputValueData(); + inputValueData.setUniqueId(uniqueId); + inputValueData.setHidden(resourceInstanceInput.isHidden()); + inputValueData.setValue(resourceInstanceInput.getValue()); + inputValueData.setType(resourceInstanceInput.getType()); + long currentTimeMillis = System.currentTimeMillis(); + inputValueData.setCreationTime(currentTimeMillis); + inputValueData.setModificationTime(currentTimeMillis); + return inputValueData; + } + + private StorageOperationStatus cloneResourceInstancePropertyValues(ComponentInstance toResourceInstance, ComponentInstance fromResourceInstance) { + + Either, TitanOperationStatus> allProperties = propertyOperation.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(fromResourceInstance.getUniqueId()); + if (allProperties.isRight()) { + TitanOperationStatus status = allProperties.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + List propertiesOnInstance = allProperties.left().value(); + if (propertiesOnInstance == null || propertiesOnInstance.isEmpty() == true) { + return StorageOperationStatus.OK; + } + + for (ComponentInstanceProperty property : propertiesOnInstance) { + + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (property.getValueUniqueUid() != null) { + property.setValueUniqueUid(null); + List rules = property.getRules(); + if (rules != null) { + for (PropertyRule propertyRule : rules) { + propertyRule.replaceFirstToken(toResourceInstance.getUniqueId()); + } + } + + } else { + continue; + } + + String resourceInstanceId = toResourceInstance.getUniqueId(); + + Either counterRes = this.increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.PROPERTY_COUNTER, true); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + return status; + } + Integer index = counterRes.left().value(); + + Either addPropertyToResourceInstance = this.addPropertyToResourceInstance(property, toResourceInstance.getUniqueId(), false, index); + + if (addPropertyToResourceInstance.isRight()) { + TitanOperationStatus status = addPropertyToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + } + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus cloneResourceInstancePropertyValues(TitanVertex toResourceInstance, ComponentInstance fromResourceInstance, Map> inputsPropMap, Resource newResource) { + + String riId = (String) titanGenericDao.getProperty(toResourceInstance, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + Either, TitanOperationStatus> allProperties = propertyOperation.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(fromResourceInstance.getUniqueId()); + List newInputs = newResource.getInputs(); + // + if (allProperties.isRight()) { + TitanOperationStatus status = allProperties.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + List propertiesOnInstance = allProperties.left().value(); + if (propertiesOnInstance == null || propertiesOnInstance.isEmpty() == true) { + return StorageOperationStatus.OK; + } + + for (ComponentInstanceProperty property : propertiesOnInstance) { + + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (property.getValueUniqueUid() != null) { + property.setValueUniqueUid(null); + List rules = property.getRules(); + if (rules != null) { + for (PropertyRule propertyRule : rules) { + propertyRule.replaceFirstToken(riId); + } + } + + } else { + continue; + } + + String resourceInstanceId = riId; + + Either counterRes = this.increaseAndGetResourceInstanceSpecificCounter(toResourceInstance, GraphPropertiesDictionary.PROPERTY_COUNTER); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + return status; + } + Integer index = counterRes.left().value(); + + Either addPropertyToResourceInstance = this.addPropertyToResourceInstance(property, toResourceInstance, false, index, resourceInstanceId); + + if (addPropertyToResourceInstance.isRight() && !addPropertyToResourceInstance.right().value().equals(TitanOperationStatus.OK)) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToResourceInstance.right().value()); + return storageStatus; + } + if (addPropertyToResourceInstance.isLeft()) { + ComponentInstanceProperty newProp = addPropertyToResourceInstance.left().value(); + Set inputsKey = inputsPropMap.keySet(); + String inputToAssName = null; + GetInputValueInfo getInputInfo = null; + for (String inputName : inputsKey) { + List propsList = inputsPropMap.get(inputName); + Optional op = propsList.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny(); + if (op.isPresent()) { + ComponentInstanceProperty inpProp = op.get(); + getInputInfo = new GetInputValueInfo(); + getInputInfo.setPropName(inpProp.getName()); + getInputInfo.setInputName(inputName); + inputToAssName = inputName; + break; + } + + } + if (inputToAssName != null) { + for (InputDefinition input1 : newInputs) { + if (input1.getName().equals(inputToAssName)) { + this.inputOperation.associatePropertyToInput(riId, input1.getUniqueId(), newProp, getInputInfo); + break; + } + } + } + + } + } + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus cloneResourceInstanceInputsValues(ComponentInstance toResourceInstance, ComponentInstance fromResourceInstance, Component comonentTo, Map> inputsValuesMap) { + + Either, TitanOperationStatus> allProperties = inputOperation.getAllInputsOfResourceInstanceOnlyInputDefId(fromResourceInstance.getUniqueId()); + if (allProperties.isRight()) { + TitanOperationStatus status = allProperties.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + List propertiesOnInstance = allProperties.left().value(); + if (propertiesOnInstance == null || propertiesOnInstance.isEmpty() == true) { + return StorageOperationStatus.OK; + } + List newInputs = comonentTo.getInputs(); + + for (ComponentInstanceInput property : propertiesOnInstance) { + + List inputToAss = new ArrayList(); + if (newInputs != null && !inputsValuesMap.isEmpty()) { + + Set inputsName = inputsValuesMap.keySet(); + for (String name : inputsName) { + List inputsValue = inputsValuesMap.get(name); + if (inputsValue != null) { + Optional op = inputsValue.stream().filter(p -> p.getValueUniqueUid().equals(property.getValueUniqueUid())).findAny(); + if (op.isPresent()) { + Optional optional = newInputs.stream().filter(e -> e.getName().equals(name)).findAny(); + if (optional.isPresent()) { + inputToAss.add(optional.get()); + } + } + } + } + } + + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (property.getValueUniqueUid() != null) { + property.setValueUniqueUid(null); + List rules = property.getRules(); + if (rules != null) { + for (PropertyRule propertyRule : rules) { + propertyRule.replaceFirstToken(toResourceInstance.getUniqueId()); + } + } + + } else { + continue; + } + + String resourceInstanceId = toResourceInstance.getUniqueId(); + + Either counterRes = this.increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.INPUT_COUNTER, true); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + return status; + } + Integer index = counterRes.left().value(); + + Either addPropertyToResourceInstance = this.addInputToResourceInstance(property, toResourceInstance.getUniqueId(), index); + + if (addPropertyToResourceInstance.isRight()) { + TitanOperationStatus status = addPropertyToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + for (InputDefinition input : inputToAss) { + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), input.getName()); + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), toResourceInstance.getUniqueId()); + + GraphNode inputData = new UniqueIdData(NodeTypeEnum.Input, input.getUniqueId()); + GraphNode propertyData = new UniqueIdData(NodeTypeEnum.InputValue, addPropertyToResourceInstance.left().value().getUniqueId()); + + Either addPropRefResult = titanGenericDao.createRelation(inputData, propertyData, GraphEdgeLabels.GET_INPUT, props); + + if (addPropRefResult.isRight()) { + TitanOperationStatus status = addPropRefResult.right().value(); + log.debug("Failed to associate input {} to input value {} in graph. Status is {}", input.getUniqueId(), propertyData.getUniqueId(), status); + + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + } + } + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus cloneResourceInstanceInputsValues(TitanVertex toResourceInstanceVertex, ComponentInstance fromResourceInstance, String instanceId, Resource newResource, Map> inputsValuesMap) { + + Either, TitanOperationStatus> allProperties = inputOperation.getAllInputsOfResourceInstanceOnlyInputDefId(fromResourceInstance.getUniqueId()); + if (allProperties.isRight()) { + TitanOperationStatus status = allProperties.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + List propertiesOnInstance = allProperties.left().value(); + if (propertiesOnInstance == null || propertiesOnInstance.isEmpty() == true) { + return StorageOperationStatus.OK; + } + + for (ComponentInstanceInput property : propertiesOnInstance) { + + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (property.getValueUniqueUid() != null) { + property.setValueUniqueUid(null); + List rules = property.getRules(); + if (rules != null) { + for (PropertyRule propertyRule : rules) { + propertyRule.replaceFirstToken(instanceId); + } + } + + } else { + continue; + } + + String resourceInstanceId = instanceId; + + Either counterRes = this.increaseAndGetResourceInstanceSpecificCounter(toResourceInstanceVertex, GraphPropertiesDictionary.INPUT_COUNTER); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + return status; + } + Integer index = counterRes.left().value(); + + Either addPropertyToResourceInstance = this.addInputToResourceInstance(property, resourceInstanceId, index); + + if (addPropertyToResourceInstance.isRight()) { + TitanOperationStatus status = addPropertyToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + } + + return StorageOperationStatus.OK; + } + + public Either updatePropertyValueInResourceInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction) { + + Either result = null; + + try { + // TODO: verify validUniqueId exists + Either eitherStatus = this.updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId, true); + + if (eitherStatus.isRight()) { + log.error("Failed to add property value {} to resource instance {} in Graph. status is {}", resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + PropertyValueData propertyValueData = eitherStatus.left().value(); + + ComponentInstanceProperty propertyValueResult = propertyOperation.buildResourceInstanceProperty(propertyValueData, resourceInstanceProperty); + + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + + Either findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceProperty.getPath(), propertyValueData.getUniqueId(), resourceInstanceProperty.getDefaultValue()); + if (findDefaultValue.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value())); + return result; + } + String defaultValue = findDefaultValue.left().value(); + propertyValueResult.setDefaultValue(defaultValue); + log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue); + + result = Either.left(propertyValueResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private static final class UpdateDataContainer { + final Wrapper valueDataWrapper; + final Wrapper dataWrapper; + final GraphEdgeLabels graphEdge; + final Supplier> someDataClassGen; + final Supplier> someValueDataClassGen; + final NodeTypeEnum nodeType; + final NodeTypeEnum nodeTypeValue; + + private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier> someDataClassGen, Supplier> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) { + super(); + this.valueDataWrapper = new Wrapper<>(); + this.dataWrapper = new Wrapper<>(); + this.graphEdge = graphEdge; + this.someDataClassGen = someDataClassGen; + this.someValueDataClassGen = someValueDataClassGen; + this.nodeType = nodeType; + this.nodeTypeValue = nodeTypeValue; + } + + public Wrapper getValueDataWrapper() { + return valueDataWrapper; + } + + public Wrapper getDataWrapper() { + return dataWrapper; + } + + public GraphEdgeLabels getGraphEdge() { + return graphEdge; + } + + public Supplier> getSomeDataClassGen() { + return someDataClassGen; + } + + public Supplier> getSomeValueDataClassGen() { + return someValueDataClassGen; + } + + public NodeTypeEnum getNodeType() { + return nodeType; + } + + public NodeTypeEnum getNodeTypeValue() { + return nodeTypeValue; + } + } + + @Override + public Either createOrUpdateAttributeOfResourceInstance(ComponentInstanceAttribute attributeInstanceProperty, String resourceInstanceId) { + Either result; + // Create + if (attributeInstanceProperty.getValueUniqueUid() == null) { + Either counterRes = increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.ATTRIBUTE_COUNTER, true); + if (counterRes.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("createOrUpdateAttributeOfResourceInstance", "Failed to get AttributeValueData Counter", ErrorSeverity.ERROR); + result = Either.right(TitanOperationStatus.GENERAL_ERROR); + + } else { + result = addAttributeToResourceInstance(attributeInstanceProperty, resourceInstanceId, counterRes.left().value()); + } + } + // Update + else { + result = updateAttributeOfResourceInstance(attributeInstanceProperty, resourceInstanceId); + } + return result; + } + + /** + * update value of attribute on resource instance + * + * @param resourceInstanceAttribute + * @param resourceInstanceId + * @return + */ + private Either updateAttributeOfResourceInstance(ComponentInstanceAttribute resourceInstanceAttribute, String resourceInstanceId) { + + Either result = null; + Wrapper errorWrapper = new Wrapper<>(); + UpdateDataContainer updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.ATTRIBUTE_IMPL, (() -> AttributeData.class), (() -> AttributeValueData.class), NodeTypeEnum.Attribute, + NodeTypeEnum.AttributeValue); + preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceAttribute, resourceInstanceId, errorWrapper); + if (errorWrapper.isEmpty()) { + AttributeValueData attributeValueData = updateDataContainer.getValueDataWrapper().getInnerElement(); + attributeValueData.setHidden(resourceInstanceAttribute.isHidden()); + attributeValueData.setValue(resourceInstanceAttribute.getValue()); + Either updateRes = titanGenericDao.updateNode(attributeValueData, AttributeValueData.class); + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + errorWrapper.setInnerElement(status); + } else { + result = Either.left(updateRes.left().value()); + } + } + if (!errorWrapper.isEmpty()) { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + + } + + private Either addAttributeToResourceInstance(ComponentInstanceAttribute attributeInstanceProperty, String resourceInstanceId, Integer index) { + Wrapper errorWrapper = new Wrapper<>(); + Wrapper compInsWrapper = new Wrapper<>(); + Wrapper attDataWrapper = new Wrapper<>(); + Wrapper attValueDataWrapper = new Wrapper<>(); + + // Verify RI Exist + validateRIExist(resourceInstanceId, compInsWrapper, errorWrapper); + + if (errorWrapper.isEmpty()) { + // Verify Attribute Exist + validateElementExistInGraph(attributeInstanceProperty.getUniqueId(), NodeTypeEnum.Attribute, () -> AttributeData.class, attDataWrapper, errorWrapper); + } + if (errorWrapper.isEmpty()) { + // Create AttributeValueData that is connected to RI + createAttributeValueDataNode(attributeInstanceProperty, index, errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper); + } + if (errorWrapper.isEmpty()) { + // Connect AttributeValueData (Att on RI) to AttData (Att on + // Resource) + connectAttValueDataToAttData(errorWrapper, attDataWrapper.getInnerElement(), attValueDataWrapper.getInnerElement()); + } + if (errorWrapper.isEmpty()) { + // Connect AttributeValueData to RI + connectAttValueDataToComponentInstanceData(errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper.getInnerElement()); + } + + if (errorWrapper.isEmpty()) { + return Either.left(attValueDataWrapper.getInnerElement()); + } else { + return Either.right(errorWrapper.getInnerElement()); + } + + } + + /** + * update value of attribute on resource instance + * + * @param resourceInstanceProerty + * @param resourceInstanceId + * @return + */ + public Either updatePropertyOfResourceInstance(ComponentInstanceProperty resourceInstanceProerty, String resourceInstanceId, boolean isValidate) { + + Wrapper errorWrapper = new Wrapper<>(); + UpdateDataContainer updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.PROPERTY_IMPL, (() -> PropertyData.class), (() -> PropertyValueData.class), NodeTypeEnum.Property, + NodeTypeEnum.PropertyValue); + + preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceProerty, resourceInstanceId, errorWrapper); + if (!errorWrapper.isEmpty()) { + return Either.right(errorWrapper.getInnerElement()); + } + + else { + String value = resourceInstanceProerty.getValue(); + // Specific Validation Logic + PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement(); + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + // Specific Update Logic + Either, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + Either isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes.left().value()); + + String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + } + PropertyValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement(); + log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue); + propertyValueData.setValue(newValue); + + ImmutablePair pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceProerty.getRules(), innerType, allDataTypes.left().value(), isValidate); + if (pair.getRight() != null && pair.getRight() == false) { + BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProerty.getName(), propertyType); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + propertyOperation.updateRulesInPropertyValue(propertyValueData, resourceInstanceProerty, resourceInstanceId); + + Either updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + return Either.right(status); + } else { + return Either.left(updateRes.left().value()); + } + } + + } + + /** + * update value of attribute on resource instance + * + * @param resourceInstanceProerty + * @param resourceInstanceId + * @return + */ + public Either updateInputOfResourceInstance(ComponentInstanceInput resourceInstanceProerty, String resourceInstanceId) { + + Wrapper errorWrapper = new Wrapper<>(); + UpdateDataContainer updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.INPUT_IMPL, (() -> PropertyData.class), (() -> InputValueData.class), NodeTypeEnum.Input, NodeTypeEnum.InputValue); + + preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceProerty, resourceInstanceId, errorWrapper); + if (!errorWrapper.isEmpty()) { + return Either.right(errorWrapper.getInnerElement()); + } + + else { + String value = resourceInstanceProerty.getValue(); + // Specific Validation Logic + PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement(); + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + // Specific Update Logic + Either, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + /* + * Either isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value()); + * + * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != + * null) { newValue = object.toString(); } } InputValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement(); log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue); propertyValueData.setValue(newValue); + * + * ImmutablePair pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceProerty.getRules(), innerType, allDataTypes.left().value()); if (pair.getRight() != null && pair.getRight() == false) { + * BeEcompErrorManager.getInstance(). logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProerty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } + * propertyOperation.updateRulesInPropertyValue(propertyValueData, resourceInstanceProerty, resourceInstanceId); + * + * Either updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); if (updateRes.isRight()) { TitanOperationStatus status = updateRes.right().value(); return + * Either.right(status); } else { return Either.left(updateRes.left().value()); } + */ + } + return null; + + } + + private void preUpdateElementOfResourceInstanceValidations(UpdateDataContainer updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty, + String resourceInstanceId, Wrapper errorWrapper) { + + if (errorWrapper.isEmpty()) { + // Verify VFC instance Exist + validateRIExist(resourceInstanceId, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + // Example: Verify Property connected to VFC exist + validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + // Example: Verify PropertyValue connected to VFC Instance exist + validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + // Example: Verify PropertyValue connected Property + validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper); + } + } + + private void validateElementConnectedToInstance(UpdateDataContainer updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty, + Wrapper errorWrapper) { + Either, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(), + updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get()); + + if (child.isRight()) { + TitanOperationStatus status = child.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + errorWrapper.setInnerElement(status); + + } else { + updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left); + } + } + + private void validateElementConnectedToComponentInstanceExist(UpdateDataContainer updateDataContainer, + IComponentInstanceConnectedElement resourceInstanceProerty, Wrapper errorWrapper) { + String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid(); + if (valueUniqueUid == null) { + errorWrapper.setInnerElement(TitanOperationStatus.INVALID_ID); + } else { + Either findPropertyValueRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid, updateDataContainer.getSomeValueDataClassGen().get()); + if (findPropertyValueRes.isRight()) { + TitanOperationStatus status = findPropertyValueRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + errorWrapper.setInnerElement(status); + } else { + updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value()); + } + } + } + + private void validateElementConnectedToComponentExist(UpdateDataContainer updateDataContainer, + IComponentInstanceConnectedElement resourceInstanceElementConnected, Wrapper errorWrapper) { + String uniqueId = resourceInstanceElementConnected.getUniqueId(); + Either findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get()); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + errorWrapper.setInnerElement(status); + } + } + + private void validateRIExist(String resourceInstanceId, Wrapper errorWrapper) { + validateRIExist(resourceInstanceId, null, errorWrapper); + } + + private void validateRIExist(String resourceInstanceId, Wrapper compInsDataWrapper, Wrapper errorWrapper) { + validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.ResourceInstance, () -> ComponentInstanceData.class, compInsDataWrapper, errorWrapper); + } + + public void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType, Supplier> elementClassGen, Wrapper elementDataWrapper, + Wrapper errorWrapper) { + Either findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get()); + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + errorWrapper.setInnerElement(status); + } else { + if (elementDataWrapper != null) { + elementDataWrapper.setInnerElement(findResInstanceRes.left().value()); + } + } + } + + /** + * add property to resource instance + * + * @param resourceInstanceProperty + * @param resourceInstanceId + * @param index + * @return + */ + public Either addPropertyToResourceInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean isValidate, Integer index) { + + Either findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String propertyId = resourceInstanceProperty.getUniqueId(); + Either findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); + if (valueUniqueUid == null) { + + PropertyData propertyData = findPropertyDefRes.left().value(); + ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value(); + + ImmutablePair isPropertyValueExists = propertyOperation.findPropertyValue(resourceInstanceId, propertyId); + if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { + log.debug("The property {} already added to the resource instance {}", propertyId, resourceInstanceId); + resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight()); + Either updatePropertyOfResourceInstance = updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId, isValidate); + if (updatePropertyOfResourceInstance.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); + return Either.right(updatePropertyOfResourceInstance.right().value()); + } + return Either.left(updatePropertyOfResourceInstance.left().value()); + } + + if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { + log.debug("After finding property value of {} on component instance {}", propertyId, resourceInstanceId); + return Either.right(isPropertyValueExists.getLeft()); + } + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + String value = resourceInstanceProperty.getValue(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + + log.debug("Before validateAndUpdatePropertyValue"); + Either, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + Either isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes.left().value()); + log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid); + + String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + } + + String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(resourceInstanceData.getUniqueId(), index); + PropertyValueData propertyValueData = new PropertyValueData(); + propertyValueData.setUniqueId(uniqueId); + propertyValueData.setValue(newValue); + + log.debug("Before validateAndUpdateRules"); + ImmutablePair pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules(), innerType, allDataTypes.left().value(), isValidate); + log.debug("After validateAndUpdateRules. pair = {}", pair); + if (pair.getRight() != null && pair.getRight() == false) { + BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + propertyOperation.addRulesToNewPropertyValue(propertyValueData, resourceInstanceProperty, resourceInstanceId); + + log.debug("Before adding property value to graph {}", propertyValueData); + Either createNodeResult = titanGenericDao.createNode(propertyValueData, PropertyValueData.class); + log.debug("After adding property value to graph {}", propertyValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + return Either.right(operationStatus); + } + propertyValueData = createNodeResult.left().value(); + + Either createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + // TODO: change logger + log.error("Failed to associate property value " + uniqueId + " to property " + propertyId + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + createRelResult = titanGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + // TODO: change logger + log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + return Either.left(propertyValueData); + } else { + log.error("property value already exists."); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + + } + + public Either addPropertyToResourceInstance(ComponentInstanceProperty resourceInstanceProperty, TitanVertex resourceInstanceVertex, boolean isValidate, Integer index, String resourceInstanceId) { + + String propertyId = resourceInstanceProperty.getUniqueId(); + Either findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); + if (valueUniqueUid == null) { + + PropertyData propertyData = findPropertyDefRes.left().value(); + + ImmutablePair isPropertyValueExists = propertyOperation.findPropertyValue(resourceInstanceId, propertyId); + if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { + log.trace("The property {} already added to the resource instance {}", propertyId, resourceInstanceId); + resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight()); + Either updatePropertyOfResourceInstance = updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId, isValidate); + if (updatePropertyOfResourceInstance.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); + return Either.right(updatePropertyOfResourceInstance.right().value()); + } + return Either.right(TitanOperationStatus.OK); + } + + if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { + log.trace("After finding property value of {} on componenet instance {}", propertyId, resourceInstanceId); + return Either.right(isPropertyValueExists.getLeft()); + } + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + String value = resourceInstanceProperty.getValue(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + + log.trace("Before validateAndUpdatePropertyValue"); + Either, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + Either isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes.left().value()); + log.trace("After validateAndUpdatePropertyValue. isValid = {}", isValid); + + String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + } + + String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(resourceInstanceId, index); + PropertyValueData propertyValueData = new PropertyValueData(); + propertyValueData.setUniqueId(uniqueId); + propertyValueData.setValue(newValue); + + log.trace("Before validateAndUpdateRules"); + ImmutablePair pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules(), innerType, allDataTypes.left().value(), isValidate); + log.debug("After validateAndUpdateRules. pair = {}", pair); + if (pair.getRight() != null && pair.getRight() == false) { + BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + propertyOperation.addRulesToNewPropertyValue(propertyValueData, resourceInstanceProperty, resourceInstanceId); + + log.trace("Before adding property value to graph {}", propertyValueData); + Either createNodeResult = titanGenericDao.createNode(propertyValueData, PropertyValueData.class); + log.trace("After adding property value to graph {}", propertyValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + return Either.right(operationStatus); + } + propertyValueData = createNodeResult.left().value(); + + Either createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + // TODO: change logger + log.error("Failed to associate property value " + uniqueId + " to property " + propertyId + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + TitanOperationStatus edgeResult = titanGenericDao.createEdge(resourceInstanceVertex, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null); + + if (!edgeResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId + " in graph. status is " + edgeResult); + return Either.right(edgeResult); + } + + ComponentInstanceProperty propertyValueResult = propertyOperation.buildResourceInstanceProperty(propertyValueData, resourceInstanceProperty); + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + + return Either.left(propertyValueResult); + } else { + log.debug("property value already exists."); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + + } + + /** + * add property to resource instance + * + * @param resourceInstanceProperty + * @param resourceInstanceId + * @param index + * @return + */ + public Either addInputToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index) { + + Either findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String propertyId = resourceInstanceInput.getUniqueId(); + Either findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), propertyId, InputsData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String valueUniqueUid = resourceInstanceInput.getValueUniqueUid(); + if (valueUniqueUid == null) { + + InputsData propertyData = findPropertyDefRes.left().value(); + + ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value(); + + ImmutablePair isInputValueExists = inputOperation.findInputValue(resourceInstanceId, propertyId); + if (isInputValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { + log.debug("The property {} already added to the resource insance {}", propertyId, resourceInstanceId); + resourceInstanceInput.setValueUniqueUid(isInputValueExists.getRight()); + /* + * Either updatePropertyOfResourceInstance = updatePropertyOfResourceInstance(resourceInstanceInput, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) { + * BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); + * return Either.right(updatePropertyOfResourceInstance.right().value() ); } return Either.left(updatePropertyOfResourceInstance.left().value()); + */ + } + + if (isInputValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { + log.debug("After finding input value of {} on compnent instance {}", propertyId, resourceInstanceId); + return Either.right(isInputValueExists.getLeft()); + } + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + String value = resourceInstanceInput.getValue(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exists", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + + log.debug("Before validateAndUpdatePropertyValue"); + Either, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + // Either isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value()); + // log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid); + + /*String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + }*/ + + String uniqueId = UniqueIdBuilder.buildResourceInstanceInputValueUid(resourceInstanceData.getUniqueId(), index); + InputValueData propertyValueData = new InputValueData(); + propertyValueData.setUniqueId(uniqueId); + propertyValueData.setValue(value); + + log.debug("Before validateAndUpdateRules"); + ImmutablePair pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceInput.getRules(), innerType, allDataTypes.left().value(), true); + log.debug("After validateAndUpdateRules. pair = {}", pair); + if (pair.getRight() != null && pair.getRight() == false) { + BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceInput.getName(), propertyType); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + // propertyOperation.addRulesToNewPropertyValue(propertyValueData, + // resourceInstanceInput, resourceInstanceId); + + log.debug("Before adding property value to graph {}", propertyValueData); + Either createNodeResult = titanGenericDao.createNode(propertyValueData, InputValueData.class); + log.debug("After adding property value to graph {}", propertyValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + return Either.right(operationStatus); + } + + Either createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.INPUT_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + // TODO: change logger + log.error("Failed to associate property value {} to property {} in graph. Status is {}", uniqueId, propertyId, operationStatus); + return Either.right(operationStatus); + } + + Map properties1 = new HashMap(); + + properties1.put(GraphEdgePropertiesDictionary.NAME.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getName()); + properties1.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getUniqueId()); + + createRelResult = titanGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.INPUT_VALUE, properties1); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + // TODO: change logger + log.error("Failed to associate resource instance {} property value {} in graph. Status is {}", resourceInstanceId, uniqueId, operationStatus); + return Either.right(operationStatus); + + } + + // inputOperation.associatePropertyToInput(resourceInstanceId, + // resourceInstanceInput.getInputId(), propertyValueData, + // resourceInstanceInput.getName()); + + return Either.left(createNodeResult.left().value()); + } else { + log.error("property value already exists."); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + + } + + @Override + public Either addAttributeValueToResourceInstance(ComponentInstanceAttribute resourceInstanceAttribute, String resourceInstanceId, Integer index, boolean inTransaction) { + Either result = null; + + try { + + Either eitherStatus = this.addAttributeToResourceInstance(resourceInstanceAttribute, resourceInstanceId, index); + + if (eitherStatus.isRight()) { + log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + AttributeValueData attributeValueData = eitherStatus.left().value(); + + ComponentInstanceAttribute attributeValueResult = attributeOperation.buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute); + log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult); + + result = Either.left(attributeValueResult); + return result; + } + } + + finally { + handleTransactionCommitRollback(inTransaction, result); + } + } + + @Override + public Either updateAttributeValueInResourceInstance(ComponentInstanceAttribute resourceInstanceAttribute, String resourceInstanceId, boolean inTransaction) { + + Either result = null; + + try { + Either eitherAttributeValue = updateAttributeOfResourceInstance(resourceInstanceAttribute, resourceInstanceId); + + if (eitherAttributeValue.isRight()) { + log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherAttributeValue.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherAttributeValue.right().value())); + return result; + } else { + AttributeValueData attributeValueData = eitherAttributeValue.left().value(); + + ComponentInstanceAttribute attributeValueResult = attributeOperation.buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute); + log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult); + + result = Either.left(attributeValueResult); + return result; + } + } + + finally { + handleTransactionCommitRollback(inTransaction, result); + } + + } + + @Override + public Either addPropertyValueToResourceInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction) { + return addPropertyValueToResourceInstance(resourceInstanceProperty, resourceInstanceId, true, index, inTransaction); + } + + @Override + public Either addPropertyValueToResourceInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean isValidate, Integer index, boolean inTransaction) { + + /// #RULES SUPPORT + /// Ignore rules received from client till support + resourceInstanceProperty.setRules(null); + /// + /// + + Either result = null; + + try { + + Either eitherStatus = addPropertyToResourceInstance(resourceInstanceProperty, resourceInstanceId, isValidate, index); + + if (eitherStatus.isRight()) { + log.error("Failed to add property value {} to resource instance {} in Graph. status is {}", resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + PropertyValueData propertyValueData = eitherStatus.left().value(); + + ComponentInstanceProperty propertyValueResult = propertyOperation.buildResourceInstanceProperty(propertyValueData, resourceInstanceProperty); + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + + Either findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceProperty.getPath(), resourceInstanceProperty.getUniqueId(), resourceInstanceProperty.getDefaultValue()); + if (findDefaultValue.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value())); + return result; + } + String defaultValue = findDefaultValue.left().value(); + propertyValueResult.setDefaultValue(defaultValue); + log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue); + + result = Either.left(propertyValueResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either addInputValueToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index, boolean inTransaction) { + + /// #RULES SUPPORT + /// Ignore rules received from client till support + resourceInstanceInput.setRules(null); + /// + /// + + Either result = null; + + try { + + Either eitherStatus = addInputToResourceInstance(resourceInstanceInput, resourceInstanceId, index); + + if (eitherStatus.isRight()) { + log.error("Failed to add input value {} to resource instance {} in Graph. status is {}", resourceInstanceInput, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + InputValueData propertyValueData = eitherStatus.left().value(); + + ComponentInstanceInput propertyValueResult = inputOperation.buildResourceInstanceInput(propertyValueData, resourceInstanceInput); + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + + Either findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceInput.getPath(), resourceInstanceInput.getUniqueId(), resourceInstanceInput.getDefaultValue()); + if (findDefaultValue.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value())); + return result; + } + String defaultValue = findDefaultValue.left().value(); + propertyValueResult.setDefaultValue(defaultValue); + log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue); + + result = Either.left(propertyValueResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either, TitanOperationStatus> getComponentInstancesProperties(List resourceInstances, Map> alreadyProcessedResources, + Map> resourceInstancesProperties, Map> processedInstances, List path) { + + List result = new ArrayList<>(); + + for (ComponentInstance componentInstance : resourceInstances) { + + path.add(componentInstance.getUniqueId()); + + Either, TitanOperationStatus> componentInstancesProperties = getComponentInstanceProperties(componentInstance, alreadyProcessedResources, resourceInstancesProperties, processedInstances, path); + if (componentInstancesProperties.isRight()) { + TitanOperationStatus status = componentInstancesProperties.right().value(); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + } + + List compInstancePropertyList = componentInstancesProperties.left().value(); + if (compInstancePropertyList != null) { + result.addAll(compInstancePropertyList); + } + + String uniqueId = componentInstance.getUniqueId(); + if (false == processedInstances.containsKey(uniqueId)) { + processedInstances.put(uniqueId, new ImmutablePair(componentInstance, path.size())); + } + path.remove(path.size() - 1); + + } + + return Either.left(result); + } + + public Either, TitanOperationStatus> getComponentInstanceProperties(ComponentInstance resourceInstance, Map> alreadyProcessedResources, + Map> alreadyProcessedInstances, Map> processedInstances, List path) { + + // 1. Go over each instance + // 1.1 get all properties of from the parents of the instance + // 1.2 get all updated properties + // 1.3 find all instances included in the parent of this instance and + // run this method on them. + if (log.isDebugEnabled()) + log.debug("Going to update properties of resource instance {}", resourceInstance.getUniqueId()); + String resourceUid = resourceInstance.getComponentUid(); + + List properties = alreadyProcessedResources.get(resourceUid); + if (properties == null) { + properties = new ArrayList<>(); + TitanOperationStatus findAllRes = propertyOperation.findAllResourcePropertiesRecursively(resourceUid, properties); + if (findAllRes != TitanOperationStatus.OK) { + return Either.right(findAllRes); + } + alreadyProcessedResources.put(resourceUid, properties); + } + + if (log.isDebugEnabled()) + log.debug("After getting properties of resource {} . Number of properties is {}", resourceUid, (properties == null ? 0 : properties.size())); + List resourceInstancePropertyList = new ArrayList<>(); + if (false == properties.isEmpty()) { + + // TODO: WE MAY HAVE INDIRECT PROPERTY VALUE ALSO IN CASE NO + // PROPERTY ON THIS COMPONENT + + // String resourceInstanceUid = resourceInstance.getUniqueId(); + + for (PropertyDefinition propertyDefinition : properties) { + + String defaultValue = propertyDefinition.getDefaultValue(); + String value = defaultValue; + String valueUid = null; + + // String propertyId = propertyDefinition.getUniqueId(); + + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(propertyDefinition, value, valueUid); + + resourceInstanceProperty.setPath(cloneList(path)); + + // TODO: currently ignore constraints since they are not inuse + // and cause to error in convertion to object. + resourceInstanceProperty.setConstraints(null); + + resourceInstancePropertyList.add(resourceInstanceProperty); + + } + + } + + OriginTypeEnum originType = resourceInstance.getOriginType(); + + Either, TitanOperationStatus> findInstancesUnderParentOfInstance = findInstancesUnderParentOfInstance(originType, resourceUid); + + if (findInstancesUnderParentOfInstance.isRight()) { + TitanOperationStatus status = findInstancesUnderParentOfInstance.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } + } else { + List listOfInstances = findInstancesUnderParentOfInstance.left().value(); + Either, TitanOperationStatus> componentInstancesProperties = getComponentInstancesProperties(listOfInstances, alreadyProcessedResources, alreadyProcessedInstances, processedInstances, path); + if (componentInstancesProperties.isRight()) { + TitanOperationStatus status = componentInstancesProperties.right().value(); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + } + List currentList = componentInstancesProperties.left().value(); + if (currentList != null) { + resourceInstancePropertyList.addAll(currentList); + } + } + + return Either.left(resourceInstancePropertyList); + } + + public Either, TitanOperationStatus> findInstancesUnderParentOfInstance(OriginTypeEnum originType, String resourceUid) { + + NodeTypeEnum containerNodeType = null; + NodeTypeEnum compInstNodeType = null; + + switch (originType) { + + case VF: + containerNodeType = NodeTypeEnum.Resource; + compInstNodeType = NodeTypeEnum.Resource; + break; + case SERVICE: + containerNodeType = NodeTypeEnum.Service; + compInstNodeType = NodeTypeEnum.Resource; + break; + case PRODUCT: + containerNodeType = NodeTypeEnum.Product; + compInstNodeType = NodeTypeEnum.Service; + case VFC: + case VL: + case CP: + break; + default: + break; + } + + if (containerNodeType == null || compInstNodeType == null) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + Either, List>, TitanOperationStatus> componentInstancesOfComponent = this.getComponentInstancesOfComponent(resourceUid, containerNodeType, compInstNodeType); + + if (componentInstancesOfComponent.isRight()) { + TitanOperationStatus status = componentInstancesOfComponent.right().value(); + log.debug("After getting instances of {} from type {}. Status is {}", resourceUid, originType, status); + return Either.right(status); + } else { + List listOfInstances = componentInstancesOfComponent.left().value().getLeft(); + if (log.isDebugEnabled()) { + String msg = "After getting instances of {} from type {} {}."; + log.debug(msg, resourceUid, originType, (listOfInstances != null ? listOfInstances.size() : 0)); + if (log.isTraceEnabled()) + log.trace(msg, resourceUid, originType, listOfInstances); + } + return Either.left(listOfInstances); + } + + } + + private List cloneList(List list) { + + if (list == null) { + return null; + } + + List clonedList = new ArrayList(); + clonedList.addAll(list); + + return clonedList; + } + + public Either>, TitanOperationStatus> findAllPropertyValueOnInstances(Map> processedInstances) { + + if (processedInstances == null) { + return Either.right(TitanOperationStatus.OK); + } + + Set>> entrySet = processedInstances.entrySet(); + + Map> propertyToInstanceValue = new HashMap<>(); + + for (Entry> entry : entrySet) { + + String compInstUniqueId = entry.getKey(); + + ImmutablePair pair = entry.getValue(); + + ComponentInstance componentInstance = pair.getLeft(); + Integer level = pair.getRight(); + + Either, TitanOperationStatus> propeprtyValueOnCIResult = findPropertyValueOnComponentInstance(componentInstance); + + if (propeprtyValueOnCIResult.isRight()) { + TitanOperationStatus status = propeprtyValueOnCIResult.right().value(); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + continue; + } + + List propertyValuesOnCI = propeprtyValueOnCIResult.left().value(); + if (propeprtyValueOnCIResult != null) { + for (ComponentInstanceProperty instanceProperty : propertyValuesOnCI) { + boolean result = addPropertyValue(compInstUniqueId, instanceProperty, propertyToInstanceValue); + if (result == false) { + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + } + } + + } + + return Either.left(propertyToInstanceValue); + } + + private boolean addPropertyValue(String compInstUniqueId, ComponentInstanceProperty instanceProperty, Map> propertyToInstanceValue) { + + String propertyUid = instanceProperty.getUniqueId(); + + Map map = propertyToInstanceValue.get(propertyUid); + if (map == null) { + map = new HashMap<>(); + propertyToInstanceValue.put(propertyUid, map); + } + + ComponentInstanceProperty putIfAbsent = map.putIfAbsent(compInstUniqueId, instanceProperty); + if (putIfAbsent != null) { + BeEcompErrorManager.getInstance().logInternalUnexpectedError("find property value", "Found 2 values on the same instance", ErrorSeverity.ERROR); + return false; + } + + return true; + + } + + private boolean addInputValue(String compInstUniqueId, ComponentInstanceInput instanceProperty, Map> propertyToInstanceValue) { + + String propertyUid = instanceProperty.getUniqueId(); + + Map map = propertyToInstanceValue.get(propertyUid); + if (map == null) { + map = new HashMap<>(); + propertyToInstanceValue.put(propertyUid, map); + } + + ComponentInstanceInput putIfAbsent = map.putIfAbsent(compInstUniqueId, instanceProperty); + if (putIfAbsent != null) { + BeEcompErrorManager.getInstance().logInternalUnexpectedError("find property value", "Found 2 values on the same instance", ErrorSeverity.ERROR); + return false; + } + + return true; + + } + + private Either, TitanOperationStatus> findPropertyValueOnComponentInstance(ComponentInstance componentInstance) { + String resourceInstanceUid = componentInstance.getUniqueId(); + OriginTypeEnum originType = componentInstance.getOriginType(); + + NodeTypeEnum instanceNodeType = findInstanceNodeTypeEnumFromOriginType(originType); + + Either, TitanOperationStatus> propertyValuesResult = propertyOperation.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid, instanceNodeType); + + log.debug("After fetching property under resource instance {}", resourceInstanceUid); + if (propertyValuesResult.isRight()) { + TitanOperationStatus status = propertyValuesResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } + return Either.right(TitanOperationStatus.OK); + } + + return Either.left(propertyValuesResult.left().value()); + + } + + private NodeTypeEnum findInstanceNodeTypeEnumFromOriginType(OriginTypeEnum originType) { + NodeTypeEnum nodeType = NodeTypeEnum.ResourceInstance; + switch (originType) { + case SERVICE: + nodeType = NodeTypeEnum.ResourceInstance; + break; + default: + break; + } + + return nodeType; + } + + /** + * add capability property values to resource instance + * + * @param resourceInstanceId + * @param capability + * @param isNewlyCreatedResourceInstance + * @return + */ + public Either>, TitanOperationStatus> addCapabilityPropertyValuesToResourceInstance(String resourceInstanceId, CapabilityDefinition capability, boolean isNewlyCreatedResourceInstance) { + log.debug("Before adding capability property values to resource instance {}.", resourceInstanceId); + TitanOperationStatus error = null; + + Either>, TitanOperationStatus> addCapInstWithPropertiesRes = capabilityInstanceOperation.createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance(resourceInstanceId, + capability.getUniqueId(), capability.getName(), capability.getProperties(), !isNewlyCreatedResourceInstance); + if (addCapInstWithPropertiesRes.isRight()) { + error = addCapInstWithPropertiesRes.right().value(); + log.debug("Failed to assotiate capability instance to resource instance {}. Status is {}", resourceInstanceId, error); + } + log.debug("After adding capability property values to resource instance {}. Status is {}", resourceInstanceId, error); + if (error == null) { + return Either.left(addCapInstWithPropertiesRes.left().value()); + } + return Either.right(error); + } + + public TitanOperationStatus addCapabilityPropertyValuesToResourceInstance(TitanVertex resourceInstanceVertex, String resourceInstanceId, CapabilityDefinition capability, boolean isNewlyCreatedResourceInstance) { + log.trace("Before adding capability property values to resource instance {}.", resourceInstanceId); + TitanOperationStatus error = TitanOperationStatus.OK; + + TitanOperationStatus addCapInstWithPropertiesRes = capabilityInstanceOperation.createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance(resourceInstanceVertex, resourceInstanceId, capability.getUniqueId(), + capability.getName(), capability.getProperties(), !isNewlyCreatedResourceInstance); + if (!addCapInstWithPropertiesRes.equals(TitanOperationStatus.OK)) { + error = addCapInstWithPropertiesRes; + log.debug("Failed to assotiate capability instance to resource instance {} . status is {}", resourceInstanceId, error); + } + log.debug("After adding capability property values to resource instance {}. Status is {}", resourceInstanceId, error); + + return error; + } + + /** + * update capability property values of capability + * + * @param resourceInstanceId + * @param capabilityId + * @param propertyValues + * @return + */ + public Either, TitanOperationStatus> updateCapabilityPropertyValuesOfResourceInstance(String resourceInstanceId, String capabilityId, List propertyValues) { + log.debug("Before updating property values of capability {} of resource instance {}.", capabilityId, resourceInstanceId); + TitanOperationStatus error = null; + Either, TitanOperationStatus> updateCapabilityPropertyValuesRes = capabilityInstanceOperation.updateCapabilityPropertyValues(resourceInstanceId, capabilityId, propertyValues); + if (updateCapabilityPropertyValuesRes.isRight()) { + error = updateCapabilityPropertyValuesRes.right().value(); + log.debug("Failed to update property values of capability {} of resource instance {}. Status is {}", capabilityId, resourceInstanceId, error); + } + log.debug("After updating property values of capability {} of resource instance {}. Status is {}", capabilityId, resourceInstanceId, error); + if (error == null) { + return Either.left(updateCapabilityPropertyValuesRes.left().value()); + } + return Either.right(error); + } + + /** + * delete property values of capability from resource instance + * + * @param capabilityId + * @param resourceInstanceId + * @return + */ + public Either deletePropertyValuesOfCapabilityFromResourceInstance(String capabilityId, String resourceInstanceId) { + log.debug("Before deleting property values of capability {} from resource instance {}.", capabilityId, resourceInstanceId); + TitanOperationStatus error = null; + Either deleteCapInstWithPropertiesRes = null; + Either getCapInstByCapabilityRes = capabilityInstanceOperation.getCapabilityInstanceOfCapabilityOfResourceInstance(resourceInstanceId, capabilityId); + if (getCapInstByCapabilityRes.isRight()) { + error = getCapInstByCapabilityRes.right().value(); + log.debug("Failed to retrieve capability instance of capability {} of resource instance {}. Status is {}", capabilityId, resourceInstanceId, error); + } + if (error == null) { + String capabilityInstanceId = getCapInstByCapabilityRes.left().value().getUniqueId(); + deleteCapInstWithPropertiesRes = capabilityInstanceOperation.deleteCapabilityInstanceFromResourceInstance(resourceInstanceId, capabilityInstanceId); + if (deleteCapInstWithPropertiesRes.isRight()) { + error = deleteCapInstWithPropertiesRes.right().value(); + log.debug("Failed to delete capability instance {} to resource instance {}. Status is {}", capabilityInstanceId, resourceInstanceId, error); + } + } + log.debug("After deleting property values of capability {} from resource instance {}. Status is {}", capabilityId, resourceInstanceId, error); + if (error == null) { + return Either.left(deleteCapInstWithPropertiesRes.left().value()); + } + return Either.right(error); + } + + /** + * clone capability instances of resource instance + * + * @param createdComponentInstance + * @param resourceInstance + * @return + */ + private Either, List>, TitanOperationStatus> cloneCapabilityInstancesOfResourceInstance(ComponentInstanceData createdComponentInstance, ComponentInstance resourceInstance) { + TitanOperationStatus error = null; + String resourceInstanceId = resourceInstance.getUniqueId(); + log.debug("Before cloning of capability instances of resource instance {}.", resourceInstanceId); + + Map, List> result = new HashMap<>(); + Either>, TitanOperationStatus> cloneAssociateCIWithPropertyValuesRes; + Either>, TitanOperationStatus> getAllCapabilityInstancesRes = capabilityInstanceOperation.getAllCapabilityInstancesOfResourceInstance(resourceInstanceId); + if (getAllCapabilityInstancesRes.isRight() && !getAllCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getAllCapabilityInstancesRes.right().value(); + log.debug("Failed to get capability instances of component instance {}. Status is {}", resourceInstanceId, error); + } + if (getAllCapabilityInstancesRes.isLeft()) { + List> capabilityInstances = getAllCapabilityInstancesRes.left().value(); + Map> allCapabilitiesMap = resourceInstance.getCapabilities(); + List allCapabilitiesList = new ArrayList<>(); + for (List curList : allCapabilitiesMap.values()) { + allCapabilitiesList.addAll(curList); + } + Map capabilities = allCapabilitiesList.stream().collect(Collectors.toMap(CapabilityDefinition::getUniqueId, Function.identity())); + String propertyName = GraphPropertiesDictionary.CAPABILITY_ID.getProperty(); + for (ImmutablePair capabilityInstPair : capabilityInstances) { + String capabilityId = (String) capabilityInstPair.getRight().getProperties().get(propertyName); + CapabilityDefinition relatedCapability = capabilities.get(capabilityId); + cloneAssociateCIWithPropertyValuesRes = capabilityInstanceOperation.cloneAssociateCapabilityInstanceWithPropertyValues(createdComponentInstance, relatedCapability, capabilityInstPair); + if (cloneAssociateCIWithPropertyValuesRes.isRight()) { + error = cloneAssociateCIWithPropertyValuesRes.right().value(); + log.debug("Failed to clone capability instances {} of component instance {}. Status is {}", capabilityInstPair.getLeft().getUniqueId(), resourceInstanceId, error); + break; + } else { + result.put(new ImmutablePair(cloneAssociateCIWithPropertyValuesRes.left().value().getLeft(), capabilityInstPair.getRight()), cloneAssociateCIWithPropertyValuesRes.left().value().getRight()); + } + } + } + log.debug("After cloning of capability instance of resource instance {}. Status is {}", resourceInstanceId, error); + if (error == null) { + return Either.left(result); + } + return Either.right(error); + } + + private Either>, TitanOperationStatus> cloneCapabilityInstancesOfResourceInstance(TitanVertex componentInstanceVertex, ComponentInstance resourceInstance) { + TitanOperationStatus error = null; + String resourceInstanceId = resourceInstance.getUniqueId(); + log.debug("Before cloning of capability instances of resource instance {}.", resourceInstanceId); + + Either cloneAssociateCIWithPropertyValuesRes = null; + Either>, TitanOperationStatus> getAllCapabilityInstancesRes = capabilityInstanceOperation.getAllCapabilityInstancesOfResourceInstance(resourceInstanceId); + if (getAllCapabilityInstancesRes.isRight() && !getAllCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getAllCapabilityInstancesRes.right().value(); + log.debug("Failed to get capability instances of component instance {}. status is {}", resourceInstanceId, error); + } + List> list = new ArrayList<>(); + if (getAllCapabilityInstancesRes.isLeft()) { + List> capabilityInstances = getAllCapabilityInstancesRes.left().value(); + Map> allCapabilitiesMap = resourceInstance.getCapabilities(); + List allCapabilitiesList = new ArrayList<>(); + for (List curList : allCapabilitiesMap.values()) { + allCapabilitiesList.addAll(curList); + } + Map capabilities = allCapabilitiesList.stream().collect(Collectors.toMap(CapabilityDefinition::getUniqueId, Function.identity())); + String propertyName = GraphPropertiesDictionary.CAPABILITY_ID.getProperty(); + for (ImmutablePair capabilityInstPair : capabilityInstances) { + String capabilityId = (String) capabilityInstPair.getRight().getProperties().get(propertyName); + CapabilityDefinition relatedCapability = capabilities.get(capabilityId); + cloneAssociateCIWithPropertyValuesRes = capabilityInstanceOperation.cloneAssociateCapabilityInstanceWithPropertyValues(componentInstanceVertex, relatedCapability, capabilityInstPair); + if (cloneAssociateCIWithPropertyValuesRes.isRight()) { + error = cloneAssociateCIWithPropertyValuesRes.right().value(); + log.debug("Failed to clone capability instances {} of component instance {}. status is {}", capabilityInstPair.getLeft().getUniqueId(), resourceInstanceId, error); + break; + } else { + list.add(new ImmutablePair(cloneAssociateCIWithPropertyValuesRes.left().value(), capabilityInstPair.right)); + } + } + } + log.debug("After cloning of capability instance of resource instance {}. Status is {}", resourceInstanceId, error); + if (error == null) { + return Either.left(list); + } + return Either.right(error); + } + + public Either, StorageOperationStatus> getAllComponentInstancesMetadataOnly(String componentId, NodeTypeEnum containerNodeType) { + + List componentInstancesResult = new ArrayList(); + Either, StorageOperationStatus> result = Either.left(componentInstancesResult); + + Either>, TitanOperationStatus> resourceInstancesRes = getAllComponentInstanceFromGraph(componentId, containerNodeType, false); + + if (resourceInstancesRes.isRight()) { + + if (log.isDebugEnabled()) { + log.debug("Resource instance was found under service {} . status is {} ", componentId, resourceInstancesRes.right().value()); + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceInstancesRes.right().value())); + } + + List> resourceInstances = resourceInstancesRes.left().value(); + if (resourceInstances != null && false == resourceInstances.isEmpty()) { + + for (ImmutablePair immutablePair : resourceInstances) { + ComponentInstanceData resourceInstanceData = immutablePair.getKey(); + if (log.isDebugEnabled()) { + log.debug("Going to fetch the relationships of resource instance {}", resourceInstanceData); + } + componentInstancesResult.add(new ComponentInstance(resourceInstanceData.getComponentInstDataDefinition())); + + } + } + + return result; + } + + public Either, TitanOperationStatus> updateCapDefPropertyValues(ComponentInstance componentInstance, List capabilityDefList) { + String componentInstanceId = componentInstance.getUniqueId(); + log.debug("Before updating property values of capabilities of component istance {}.", componentInstanceId); + TitanOperationStatus error = null; + NodeTypeEnum nodeType = NodeTypeEnum.getByNameIgnoreCase(componentInstance.getOriginType().getInstanceType().trim()); + + log.debug("Before getting all capability instances of component istance {}.", componentInstanceId); + Either>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), componentInstanceId, GraphEdgeLabels.CAPABILITY_INST, + NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + if (getCapabilityInstancesRes.isRight() && !getCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability Instances of resource instance {}. Status is {}", componentInstance.getName(), error); + } + log.debug("After getting all capability instances of component istance {}. Status is {}", componentInstanceId, error); + Map> overridedCapabilitiesHM = new HashMap<>(); + if (getCapabilityInstancesRes.isLeft()) { + List> capabilityInstDataPair = getCapabilityInstancesRes.left().value(); + + for (ImmutablePair curCapabilityPair : capabilityInstDataPair) { + CapabilityInstData curCapabilityInst = curCapabilityPair.getLeft(); + String curCapInstUid = curCapabilityInst.getUniqueId(); + + log.debug("Before getting all property values of capability instance {} of component istance {}.", curCapInstUid, componentInstanceId); + Either>, TitanOperationStatus> getOverridedPropertyValuesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(curCapabilityInst.getLabel())), + curCapInstUid, GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, PropertyValueData.class); + if (getOverridedPropertyValuesRes.isRight()) { + error = getOverridedPropertyValuesRes.right().value(); + log.debug("Failed to retrieve property values of capability instance {}. Status is {}", curCapInstUid, error); + } + + log.debug("After getting all property values of capability instance {} of component istance {}. Status is {}", curCapInstUid, componentInstanceId, error); + Map overridedPropertyValuesHM = new HashMap<>(); + List> overridedPropertyValues = getOverridedPropertyValuesRes.left().value(); + for (ImmutablePair curPropertyValuePair : overridedPropertyValues) { + PropertyValueData curPropertyValue = curPropertyValuePair.getLeft(); + String propertyValueUid = curPropertyValue.getUniqueId(); + log.debug("Before getting property related to property value {} of capability instance {} of component istance {}.", propertyValueUid, curCapInstUid, componentInstanceId); + Either, TitanOperationStatus> getPropertyDataRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(curPropertyValue.getLabel())), propertyValueUid, + GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (getPropertyDataRes.isRight()) { + error = getOverridedPropertyValuesRes.right().value(); + log.debug("Failed to retrieve property of property value {} Status is {}", propertyValueUid, error); + } + + if (log.isDebugEnabled()) { + log.debug("After getting property related to property value {} of capability instance {} of component istance {}. Status is {}", propertyValueUid, curCapInstUid, componentInstanceId, error); + } + PropertyData propertyData = getPropertyDataRes.left().value().getLeft(); + overridedPropertyValuesHM.put((String) propertyData.getUniqueId(), curPropertyValue); + } + overridedCapabilitiesHM.put((String) curCapabilityPair.getRight().getProperties().get(GraphPropertiesDictionary.CAPABILITY_ID.getProperty()), overridedPropertyValuesHM); + } + } + if (error == null && !overridedCapabilitiesHM.isEmpty()) { + updateCapabilityPropertyValues(componentInstance.getCapabilities(), capabilityDefList, overridedCapabilitiesHM); + } + log.debug("After updating property values of capabilities of component istance {}. Status is {}", componentInstanceId, error); + if (error == null) { + return Either.left(capabilityDefList); + } + return Either.right(error); + } + + private void updateCapabilityPropertyValues(Map> capabilitiesOfRI, List capabilitiesOfContainer, Map> overridedCapabilitiesHM) { + + capabilitiesOfContainer.stream().filter(capability -> overridedCapabilitiesHM.containsKey(capability.getUniqueId())).forEach(capability -> { + boolean updateProperties = false; + for (ComponentInstanceProperty property : capability.getProperties()) { + if (overridedCapabilitiesHM.get(capability.getUniqueId()).containsKey(property.getUniqueId())) { + property.setValue(overridedCapabilitiesHM.get(capability.getUniqueId()).get(property.getUniqueId()).getValue()); + property.setValueUniqueUid(overridedCapabilitiesHM.get(capability.getUniqueId()).get(property.getUniqueId()).getUniqueId()); + updateProperties = true; + } + } + if (updateProperties) { + capabilitiesOfRI.get(capability.getType()).get(0).setProperties(capability.getProperties()); + } + }); + } + + @Override + public Either updateInputValueInResourceInstance(ComponentInstanceInput input, String resourceInstanceId, boolean b) { + // TODO Auto-generated method stub + return null; + } + + public Either, StorageOperationStatus> fetchCIEnvArtifacts(String componentInstanceId) { + Either, StorageOperationStatus> result = artifactOperation.getArtifacts(componentInstanceId, NodeTypeEnum.ResourceInstance, true, ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + if (result.isRight() && result.right().value() == StorageOperationStatus.NOT_FOUND) + return Either.right(StorageOperationStatus.OK); + return result; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperation.java new file mode 100644 index 0000000000..b243c6ea4d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperation.java @@ -0,0 +1,2886 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +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.UUID; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.commons.lang3.tuple.Pair; +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.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +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.QueryType; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanGraphClient; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; +import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +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.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +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.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.GroupDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.cache.ComponentCache; +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.IAdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.ICapabilityOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IRequirementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ProductMetadataData; +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.UniqueIdData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.GroupingData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.be.utils.CommonBeUtils; +import org.openecomp.sdc.be.workers.Job; +import org.openecomp.sdc.be.workers.Manager; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.util.StreamUtils; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanGraphQuery; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public abstract class ComponentOperation { + private static Logger log = LoggerFactory.getLogger(ComponentOperation.class.getName()); + + @Autowired + protected TitanGenericDao titanGenericDao; + + @Autowired + protected IArtifactOperation artifactOperation; + + @Autowired + protected IElementOperation elementOperation; + + @Autowired + protected ICapabilityOperation capabilityOperation; + + @Autowired + protected IRequirementOperation requirementOperation; + + @Autowired + protected ComponentInstanceOperation componentInstanceOperation; + + @Autowired + private PropertyOperation propertyOperation; + + @Autowired + protected InputsOperation inputOperation; + + @Autowired + protected IAdditionalInformationOperation additionalInformationOperation; + + @Autowired + protected GroupOperation groupOperation; + + @Autowired + protected InputsOperation inputsOperation; + + @Autowired + protected ApplicationDataTypeCache applicationDataTypeCache; + + @Autowired + private ComponentCache componentCache; + + private static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1"); + + protected Gson prettyJson = new GsonBuilder().setPrettyPrinting().create(); + + protected Either, StorageOperationStatus> createNewTagsList(List tags) { + + List existingTags = new ArrayList(); + List tagsToCreate = new ArrayList(); + Either, TitanOperationStatus> either = titanGenericDao.getAll(NodeTypeEnum.Tag, TagData.class); + + if ((either.isRight()) && (either.right().value() != TitanOperationStatus.NOT_FOUND)) { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } else if (either.isLeft()) { + existingTags = either.left().value(); + } + + for (String tagName : tags) { + TagData tag = new TagData(tagName); + if ((existingTags == null) || (!existingTags.contains(tag))) { + tagsToCreate.add(tag); + } + } + return Either.left(tagsToCreate); + + } + + protected StorageOperationStatus createTagNodesOnGraph(List tagsToCreate) { + StorageOperationStatus result = StorageOperationStatus.OK; + // In order to avoid duplicate tags + tagsToCreate = ImmutableSet.copyOf(tagsToCreate).asList(); + if (tagsToCreate != null && false == tagsToCreate.isEmpty()) { + for (TagData tagData : tagsToCreate) { + log.debug("Before creating tag {}", tagData); + Either createTagResult = titanGenericDao.createNode(tagData, TagData.class); + if (createTagResult.isRight()) { + TitanOperationStatus status = createTagResult.right().value(); + log.error("Cannot create {} in the graph. Status is {}", tagData, status); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + + } + log.debug("After creating tag {}", tagData); + } + } + return result; + } + + public Either getLatestComponentByUuid(NodeTypeEnum nodeType, String uuid) { + Either getComponentResult = null; + Either latestComponentMetadataRes = getLatestComponentMetadataByUuid(nodeType, uuid); + if (latestComponentMetadataRes.isRight()) { + getComponentResult = Either.right(latestComponentMetadataRes.right().value()); + } + if (getComponentResult == null) { + ComponentMetadataData latestVersion = latestComponentMetadataRes.left().value(); + String id = latestVersion.getMetadataDataDefinition().getUniqueId(); + Either component = getComponent(id, false); + if (component.isRight()) { + log.debug("Couldn't fetch component with type {} and id {}, error: {}", nodeType, id, component.right().value()); + getComponentResult = Either.right(component.right().value()); + } else { + getComponentResult = Either.left(component.left().value()); + } + } + return getComponentResult; + } + + public Either getLatestComponentMetadataByUuid(NodeTypeEnum nodeType, String uuid) { + + Either getComponentResult = null; + List latestVersionList = null; + ComponentMetadataData latestVersion = null; + + Map propertiesToMatch = new HashMap(); + propertiesToMatch.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either, TitanOperationStatus> getComponentEither = titanGenericDao.getByCriteria(nodeType, propertiesToMatch, ComponentMetadataData.class); + if (getComponentEither.isRight()) { + log.debug("Couldn't fetch metadata for component with type {} and uuid {}, error: {}", nodeType, uuid, getComponentEither.right().value()); + getComponentResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentEither.right().value())); + + } + if (getComponentResult == null) { + latestVersionList = getComponentEither.left().value(); + if (latestVersionList.isEmpty()) { + log.debug("Component with type {} and uuid {} was not found", nodeType, uuid); + getComponentResult = Either.right(StorageOperationStatus.NOT_FOUND); + } + } + if (getComponentResult == null) { + latestVersion = latestVersionList.size() == 1 ? latestVersionList.get(0) + : latestVersionList.stream().max((c1, c2) -> Double.compare(Double.parseDouble(c1.getMetadataDataDefinition().getVersion()), Double.parseDouble(c2.getMetadataDataDefinition().getVersion()))).get(); + getComponentResult = Either.left(latestVersion); + } + return getComponentResult; + } + + public Either getComponentByLabelAndId(String uniqueId, NodeTypeEnum nodeType, Class clazz) { + + Map propertiesToMatch = new HashMap(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId); + Either, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(nodeType, propertiesToMatch, clazz); + if (getResponse.isRight()) { + log.debug("Couldn't fetch component with type {} and unique id {}, error: {}", nodeType, uniqueId, getResponse.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value())); + + } + List serviceDataList = getResponse.left().value(); + if (serviceDataList.isEmpty()) { + log.debug("Component with type {} and unique id {} was not found", nodeType, uniqueId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + T serviceData = serviceDataList.get(0); + return Either.left(serviceData); + } + + // protected Either + // getComponentByLabelAndId_tx(String uniqueId, NodeTypeEnum nodeType, + // Class clazz) { + // + // Map propertiesToMatch = new HashMap(); + // propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(nodeType), + // uniqueId); + // Either, TitanOperationStatus> getResponse = + // titanGenericDao.getByCriteria_tx(nodeType, propertiesToMatch, clazz); + // if (getResponse.isRight()) { + // log.debug("Couldn't fetch component with type {} and unique id {}, error: + // {}", nodeType, uniqueId, getResponse.right().value()); + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value())); + // + // } + // List serviceDataList = getResponse.left().value(); + // if (serviceDataList.isEmpty()) { + // log.debug("Component with type {} and unique id {} was not found", + // nodeType, uniqueId); + // return Either.right(StorageOperationStatus.NOT_FOUND); + // } + // T serviceData = serviceDataList.get(0); + // return Either.left(serviceData); + // } + + /** + * + * @param component + * @param uniqueId + * @param nodeType + * @return + */ + protected TitanOperationStatus setComponentCreatorFromGraph(Component component, String uniqueId, NodeTypeEnum nodeType) { + Either, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.CREATOR, NodeTypeEnum.User, UserData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + ImmutablePair value = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + UserData userData = value.getKey(); + if (log.isDebugEnabled()) + log.debug("Build resource : set creator userId to {}", userData.getUserId()); + String fullName = buildFullName(userData); + if (log.isDebugEnabled()) + log.debug("Build resource : set last modifier full name to {} ", fullName); + component.setCreatorUserId(userData.getUserId()); + component.setCreatorFullName(fullName); + + return TitanOperationStatus.OK; + } + + protected TitanOperationStatus setComponentLastModifierFromGraph(Component component, String uniqueId, NodeTypeEnum nodeType) { + + Either, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.LAST_MODIFIER, NodeTypeEnum.User, UserData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + ImmutablePair value = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + UserData userData = value.getKey(); + + if (log.isDebugEnabled()) + log.debug("Build resource : set last modifier userId to {}", userData.getUserId()); + String fullName = buildFullName(userData); + if (log.isDebugEnabled()) + log.debug("Build resource : set last modifier full name to {}", fullName); + component.setLastUpdaterUserId(userData.getUserId()); + component.setLastUpdaterFullName(fullName); + + return TitanOperationStatus.OK; + } + + /** + * + * @param userData + * @return + */ + protected String buildFullName(UserData userData) { + + String fullName = userData.getFirstName(); + if (fullName == null) { + fullName = ""; + } else { + fullName = fullName + " "; + } + String lastName = userData.getLastName(); + if (lastName != null) { + fullName += lastName; + } + return fullName; + } + + protected Either findUser(String userId) { + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + Either findUser = titanGenericDao.getNode(key, userId, UserData.class); + return findUser; + } + + protected Either findUserVertex(String userId) { + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + return titanGenericDao.getVertexByProperty(key, userId); + } + + protected Either findGrouping(NodeTypeEnum nodeType, String groupingId) { + String key = UniqueIdBuilder.getKeyByNodeType(nodeType); + Either findGrouping = titanGenericDao.getNode(key, groupingId, GroupingData.class); + return findGrouping; + } + + protected Either findSubCategory(NodeTypeEnum nodeType, String subCategoryId) { + String key = UniqueIdBuilder.getKeyByNodeType(nodeType); + Either findSubCategory = titanGenericDao.getNode(key, subCategoryId, SubCategoryData.class); + return findSubCategory; + } + + protected Either findCategory(NodeTypeEnum nodeType, String categoryId) { + String key = UniqueIdBuilder.getKeyByNodeType(nodeType); + Either findCategory = titanGenericDao.getNode(key, categoryId, CategoryData.class); + return findCategory; + } + + protected TitanOperationStatus associateMetadataToComponent(ComponentMetadataData componentData, UserData userData, UserData updater, CategoryData categoryData, List derivedResources) { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), componentData.getMetadataDataDefinition().getState()); + Either result = titanGenericDao.createRelation(updater, componentData, GraphEdgeLabels.STATE, props); + log.debug("After associating user {} to component {}. Edge type is {}", updater, componentData.getUniqueId(), GraphEdgeLabels.STATE); + if (result.isRight()) { + return result.right().value(); + } + + result = titanGenericDao.createRelation(updater, componentData, GraphEdgeLabels.LAST_MODIFIER, null); + log.debug("After associating user {} to component {}. Edge type is {}", updater, componentData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + if (result.isRight()) { + log.error("Failed to associate user " + updater + " to component " + componentData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.LAST_MODIFIER); + return result.right().value(); + } + + result = titanGenericDao.createRelation(userData, componentData, GraphEdgeLabels.CREATOR, null); + log.debug("After associating user {} to component {}. Edge type is {}", userData, componentData.getUniqueId(), GraphEdgeLabels.CREATOR); + if (result.isRight()) { + log.error("Failed to associate user " + userData + " to component " + componentData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.CREATOR); + return result.right().value(); + } + + if (derivedResources != null) { + for (ResourceMetadataData derivedResource : derivedResources) { + log.debug("After associating component {} to parent component {}. Egde type is {}", componentData.getUniqueId(), derivedResource.getUniqueId(), GraphEdgeLabels.DERIVED_FROM); + result = titanGenericDao.createRelation(componentData, derivedResource, GraphEdgeLabels.DERIVED_FROM, null); + if (result.isRight()) { + log.error("Failed to associate user {} to component {}. Edge type is {}", userData, componentData.getUniqueId(), GraphEdgeLabels.CREATOR); + return result.right().value(); + } + } + } + + if (categoryData != null) { + result = titanGenericDao.createRelation(componentData, categoryData, GraphEdgeLabels.CATEGORY, null); + log.debug("After associating component {} to category {}. Edge type is {}", componentData.getUniqueId(), categoryData, GraphEdgeLabels.CATEGORY); + if (result.isRight()) { + log.error("Faield to associate component {} to category {}. Edge type is {}", componentData.getUniqueId(), categoryData, GraphEdgeLabels.CATEGORY); + return result.right().value(); + } + } + + return TitanOperationStatus.OK; + } + + protected StorageOperationStatus associateArtifactsToComponent(NodeTypeEnum nodeType, ComponentMetadataData componentData, Map artifacts) { + + if (artifacts != null) { + for (Entry entry : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + Either addArifactToResource = Either.left(artifactDefinition); + // if ((artifactDefinition.getUniqueId() != null) && + // !artifactDefinition.getUniqueId().isEmpty()) { + addArifactToResource = artifactOperation.addArifactToComponent(artifactDefinition, (String) componentData.getUniqueId(), nodeType, false, true); + // } + + if (addArifactToResource.isRight()) { + return addArifactToResource.right().value(); + } + } + } + return StorageOperationStatus.OK; + + } + + protected Either validateResourceNameUniqueness(String name, Map hasProps, Map hasNotProps, TitanGenericDao titanGenericDao) { + if (hasProps == null) { + hasProps = new HashMap(); + } + String normalizedName = ValidationUtils.normaliseComponentName(name); + hasProps.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + + Either, TitanOperationStatus> resources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, hasProps, hasNotProps, ResourceMetadataData.class); + if (resources.isRight() && resources.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to get resources from graph with property name: {}", name); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resources.right().value())); + } + List resourceList = (resources.isLeft() ? resources.left().value() : null); + if (resourceList != null && resourceList.size() > 0) { + if (log.isDebugEnabled()) { + StringBuilder builder = new StringBuilder(); + for (ResourceMetadataData resourceData : resourceList) { + builder.append(resourceData.getUniqueId() + "|"); + } + log.debug("resources with property name: {} exists in graph. Found {}", name, builder.toString()); + } + return Either.left(false); + } else { + log.debug("resources with property name:" + name + " does not exists in graph"); + return Either.left(true); + } + + } + + protected Either validateToscaResourceNameUniqueness(String name, TitanGenericDao titanGenericDao) { + Map properties = new HashMap<>(); + + properties.put(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), name); + + Either, TitanOperationStatus> resources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, properties, ResourceMetadataData.class); + if (resources.isRight() && resources.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to get resources from graph with property name:" + name); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resources.right().value())); + } + List resourceList = (resources.isLeft() ? resources.left().value() : null); + if (resourceList != null && resourceList.size() > 0) { + if (log.isDebugEnabled()) { + StringBuilder builder = new StringBuilder(); + for (ResourceMetadataData resourceData : resourceList) { + builder.append(resourceData.getUniqueId() + "|"); + } + log.debug("resources with property name:" + name + " exists in graph. found " + builder.toString()); + } + return Either.left(false); + } else { + log.debug("resources with property name: {} dows not exists in the graph", name); + return Either.left(true); + } + + } + + protected Either validateServiceNameUniqueness(String name, TitanGenericDao titanGenericDao) { + Map properties = new HashMap<>(); + String normalizedName = ValidationUtils.normaliseComponentName(name); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + + Either, TitanOperationStatus> services = titanGenericDao.getByCriteria(NodeTypeEnum.Service, properties, ServiceMetadataData.class); + if (services.isRight() && services.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to get services from graph with property name: {}", name); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(services.right().value())); + } + List serviceList = (services.isLeft() ? services.left().value() : null); + if (serviceList != null && serviceList.size() > 0) { + if (log.isDebugEnabled()) { + StringBuilder builder = new StringBuilder(); + for (ServiceMetadataData serviceData : serviceList) { + builder.append(serviceData.getUniqueId() + "|"); + } + log.debug("Service with property name: {} exists in graph. Found {}", name, builder.toString()); + } + + return Either.left(false); + } else { + log.debug("Service with property name: {} dows not exists in graph", name); + return Either.left(true); + } + } + + protected Either validateComponentNameUniqueness(String name, TitanGenericDao titanGenericDao, NodeTypeEnum type) { + Map properties = new HashMap<>(); + String normalizedName = ValidationUtils.normaliseComponentName(name); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + + Either, TitanOperationStatus> components = titanGenericDao.getByCriteria(type, properties, ComponentMetadataData.class); + if (components.isRight() && components.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to get components from graph with property name: {}", name); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(components.right().value())); + } + List componentList = (components.isLeft() ? components.left().value() : null); + if (componentList != null && componentList.size() > 0) { + if (log.isDebugEnabled()) { + StringBuilder builder = new StringBuilder(); + for (ComponentMetadataData componentData : componentList) { + builder.append(componentData.getUniqueId() + "|"); + } + log.debug("Component with property name: {} exists in graph. Found {}", name, builder.toString()); + } + + return Either.left(false); + } else { + log.debug("Component with property name: {} does not exists in graph", name); + return Either.left(true); + } + } + + // protected TitanOperationStatus setComponentCategoryFromGraph(String + // uniqueId, Component component, TitanGenericDao titanGenericDao, + // NodeTypeEnum categoryType) { + // + // Either>, + // TitanOperationStatus> parentNode = + // titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), + // uniqueId, GraphEdgeLabels.CATEGORY, categoryType, + // CategoryData.class); + // if (parentNode.isRight()) { + // return parentNode.right().value(); + // } + // + // List> listValue = + // parentNode.left().value(); + // log.debug("Result after looking for category nodes pointed by resource " + // + uniqueId + ". status is " + listValue); + // if (listValue.size() > 1) { + // log.error("Multiple edges foud between resource " + uniqueId + " to + // category nodes."); + // } + // ImmutablePair value = listValue.get(0); + // log.debug("Found parent node {}", value); + // + // CategoryData categoryData = value.getKey(); + // String categoryStr = null; + // if + // (NodeTypeEnum.ResourceCategory.name().equalsIgnoreCase(categoryData.getLabel())) + // { + // StringBuilder sb = new StringBuilder(); + // sb.append(((ResourceCategoryData) categoryData).getCategoryName()); + // sb.append("/"); + // sb.append(categoryData.getName()); + // categoryStr = sb.toString(); + // } else { + // categoryStr = categoryData.getName(); + // } + // + // component.setCategory(categoryStr); + // return TitanOperationStatus.OK; + // } + + protected StorageOperationStatus setArtifactFromGraph(String uniqueId, Component component, NodeTypeEnum type, IArtifactOperation artifactOperation) { + StorageOperationStatus result = StorageOperationStatus.OK; + Either, StorageOperationStatus> artifacts = artifactOperation.getArtifacts(uniqueId, type, true); + if (artifacts.isRight()) { + result = artifacts.right().value(); + } else { + // component.setArtifacts(artifacts.left().value()); + createSpecificArtifactList(component, artifacts.left().value()); + } + return result; + } + + protected Component createSpecificArtifactList(Component component, Map artifacts) { + + if (artifacts != null) { + Map deploymentArtifacts = new HashMap<>(); + Map serviceApiArtifacts = new HashMap<>(); + Map toscaArtifacts = new HashMap<>(); + + Set> specificet = new HashSet<>(); + + for (Entry entry : artifacts.entrySet()) { + ArtifactDefinition artifact = entry.getValue(); + ArtifactGroupTypeEnum artifactGroupType = artifact.getArtifactGroupType(); + if (artifactGroupType == null) { + artifactGroupType = ArtifactGroupTypeEnum.INFORMATIONAL; + } + + switch (artifactGroupType) { + case DEPLOYMENT: + deploymentArtifacts.put(artifact.getArtifactLabel(), artifact); + specificet.add(entry); + break; + case SERVICE_API: + serviceApiArtifacts.put(artifact.getArtifactLabel(), artifact); + specificet.add(entry); + break; + case TOSCA: + toscaArtifacts.put(artifact.getArtifactLabel(), artifact); + specificet.add(entry); + break; + default: + break; + } + + } + artifacts.entrySet().removeAll(specificet); + + component.setSpecificComponetTypeArtifacts(serviceApiArtifacts); + component.setDeploymentArtifacts(deploymentArtifacts); + component.setToscaArtifacts(toscaArtifacts); + component.setArtifacts(artifacts); + } + return component; + } + + private Either, StorageOperationStatus> collectComponents(TitanGraph graph, NodeTypeEnum neededType, String categoryUid, NodeTypeEnum categoryType, Class clazz) { + List components = new ArrayList<>(); + Either>, TitanOperationStatus> parentNodes = titanGenericDao.getParentNodes(UniqueIdBuilder.getKeyByNodeType(categoryType), categoryUid, GraphEdgeLabels.CATEGORY, neededType, clazz); + if (parentNodes.isLeft()) { + for (ImmutablePair component : parentNodes.left().value()) { + ComponentMetadataDataDefinition componentData = component.getLeft().getMetadataDataDefinition(); + Boolean isHighest = componentData.isHighestVersion(); + Boolean isComplex = neededType == NodeTypeEnum.Resource ? ResourceTypeEnum.VF.equals(((ResourceMetadataDataDefinition) componentData).getResourceType()) : true; + if (isHighest && isComplex) { + Either result = getLightComponent(componentData.getUniqueId(), true); + if (result.isRight()) { + return Either.right(result.right().value()); + } + components.add(result.left().value()); + } + } + } + return Either.left(components); + } + + protected Either, StorageOperationStatus> fetchByCategoryOrSubCategoryUid(String categoryUid, NodeTypeEnum categoryType, String categoryLabel, NodeTypeEnum neededType, boolean inTransaction, + Class clazz) { + try { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + + } + return collectComponents(graph.left().value(), neededType, categoryUid, categoryType, clazz); + + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + protected Either, StorageOperationStatus> fetchByCategoryOrSubCategoryName(String categoryName, NodeTypeEnum categoryType, String categoryLabel, NodeTypeEnum neededType, boolean inTransaction, + Class clazz) { + List components = new ArrayList<>(); + try { + Class categoryClazz = categoryType == NodeTypeEnum.ServiceNewCategory ? CategoryData.class : SubCategoryData.class; + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), categoryName); + Either, TitanOperationStatus> getCategory = titanGenericDao.getByCriteria(categoryType, props, categoryClazz); + if (getCategory.isRight()) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + + } + for (GraphNode category : getCategory.left().value()) { + Either, StorageOperationStatus> result = collectComponents(graph.left().value(), neededType, (String) category.getUniqueId(), categoryType, clazz); + if (result.isRight()) { + return result; + } + components.addAll(result.left().value()); + } + + return Either.left(components); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + Either, StorageOperationStatus> getFilteredComponents(Map filters, boolean inTransaction, NodeTypeEnum neededType) { + return null; + } + + protected Either, StorageOperationStatus> getFollowedComponent(String userId, Set lifecycleStates, Set lastStateStates, boolean inTransaction, TitanGenericDao titanGenericDao, + NodeTypeEnum neededType) { + + Either, StorageOperationStatus> result = null; + + try { + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + return result; + } + Iterable users; + + if (userId == null) { + // get all users by label + // for Tester and Admin retrieve all users + + // users = + // graph.left().value().getVertices(GraphPropertiesDictionary.LABEL.getProperty(), + // NodeTypeEnum.User.getName()); + users = graph.left().value().query().has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.User.getName()).vertices(); + + } else { + // for Designer retrieve specific user + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + // users = graph.left().value().getVertices(key, userId); + users = graph.left().value().query().has(key, userId).vertices(); + } + Iterator userIterator = users.iterator(); + + List components = new ArrayList<>(); + while (userIterator.hasNext()) { + Vertex vertexUser = userIterator.next(); + + // get all resource with current state + Iterator iterator = vertexUser.edges(Direction.OUT, GraphEdgeLabels.STATE.getProperty()); + + List componentsPerUser = fetchComponents(lifecycleStates, iterator, neededType, inTransaction); + + HashSet ids = new HashSet(); + + if (componentsPerUser != null) { + for (Component comp : componentsPerUser) { + ids.add(comp.getUniqueId()); + components.add(comp); + } + } + + if (lastStateStates != null && !lastStateStates.isEmpty()) { + // get all resource with last state + iterator = vertexUser.edges(Direction.OUT, GraphEdgeLabels.LAST_STATE.getProperty()); + boolean isFirst; + componentsPerUser = fetchComponents(lastStateStates, iterator, neededType, inTransaction); + if (componentsPerUser != null) { + for (Component comp : componentsPerUser) { + isFirst = true; + + if (ids.contains(comp.getUniqueId())) { + isFirst = false; + } + if (isFirst == true) { + components.add(comp); + } + + } + } + } + + } // whlile users + + result = Either.left(components); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + + } + + private List fetchComponents(Set lifecycleStates, Iterator iterator, NodeTypeEnum neededType, boolean inTransaction) { + List components = new ArrayList<>(); + while (iterator.hasNext()) { + Edge edge = iterator.next(); + + String stateStr = edge.value(GraphEdgePropertiesDictionary.STATE.getProperty()); + LifecycleStateEnum state = LifecycleStateEnum.findState(stateStr); + if (state == null) { + log.debug("not supported STATE for element {}", stateStr); + continue; + } + if (lifecycleStates != null && lifecycleStates.contains(state)) { + Vertex vertexComponent = edge.inVertex(); + + Boolean isHighest = vertexComponent.value(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty()); + if (isHighest) { + + String nodeTypeStr = vertexComponent.value(GraphPropertiesDictionary.LABEL.getProperty()); + // get only latest versions + NodeTypeEnum nodeType = NodeTypeEnum.getByName(nodeTypeStr); + + if (nodeType == null) { + log.debug("missing node label for vertex {}", vertexComponent); + continue; + } + + if (neededType.equals(nodeType)) { + switch (nodeType) { + case Service: + handleNode(components, vertexComponent, nodeType, inTransaction); + break; + case Resource: + Boolean isAbtract = vertexComponent.value(GraphPropertiesDictionary.IS_ABSTRACT.getProperty()); + if (false == isAbtract) { + handleNode(components, vertexComponent, nodeType, inTransaction); + } // if not abstract + break; + case Product: + handleNode(components, vertexComponent, nodeType, inTransaction); + break; + default: + log.debug("not supported node type {}", nodeType); + break; + }// case + } // needed type + } + } // if + } // while resources + return components; + } + + protected void handleNode(List components, Vertex vertexComponent, NodeTypeEnum nodeType, boolean inTransaction) { + String id; + + id = vertexComponent.value(UniqueIdBuilder.getKeyByNodeType(nodeType)); + if (id != null) { + Either component = getLightComponent(id, inTransaction); + if (component.isRight()) { + log.debug("Failed to get component for id = {} error: {} skip resource", id, component.right().value()); + } else { + components.add(component.left().value()); + } + } else { + + Map properties = this.titanGenericDao.getProperties(vertexComponent); + log.debug("missing resource unique id for node with properties {}", properties); + } + } + + /** + * + * @param component + * @param inTransaction + * @param titanGenericDao + * @param clazz + * @return + */ + public Either updateComponent(Component component, boolean inTransaction, TitanGenericDao titanGenericDao, Class clazz, NodeTypeEnum type) { + + ComponentParametersView componentParametersView = new ComponentParametersView(); + return updateComponentFilterResult(component, inTransaction, titanGenericDao, clazz, type, componentParametersView); + + } + + private Either generateAndUpdateToscaFileName(String componentType, String componentName, String componentId, NodeTypeEnum type, ArtifactDefinition artifactInfo) { + Map getConfig = (Map) ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts().entrySet().stream().filter(p -> p.getKey().equalsIgnoreCase(artifactInfo.getArtifactLabel())) + .findAny().get().getValue(); + artifactInfo.setArtifactName(componentType + "-" + componentName + getConfig.get("artifactName")); + return artifactOperation.updateToscaArtifactNameOnGraph(artifactInfo, artifactInfo.getUniqueId(), type, componentId); + } + + protected StorageOperationStatus moveCategoryEdge(Component component, ComponentMetadataData componentData, CategoryDefinition newCategory, NodeTypeEnum type) { + + StorageOperationStatus result = StorageOperationStatus.OK; + + GraphRelation categoryRelation = new GraphRelation(); + categoryRelation.setType(GraphEdgeLabels.CATEGORY.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(type, UniqueIdBuilder.getKeyByNodeType(type), component.getUniqueId()); + categoryRelation.setFrom(relationEndPoint); + Either deleteOutgoingRelation = titanGenericDao.deleteOutgoingRelation(categoryRelation); + if (deleteOutgoingRelation.isRight()) { + log.error("Failed to delete category from component {}. Edge type is {}", componentData.getUniqueId(), GraphEdgeLabels.CATEGORY); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteOutgoingRelation.right().value()); + return result; + } + + log.debug("After removing edge from graph {}", deleteOutgoingRelation); + + NodeTypeEnum categoryType; + if (NodeTypeEnum.Service.name().equalsIgnoreCase(type.name())) { + categoryType = NodeTypeEnum.ServiceCategory; + } else { + categoryType = NodeTypeEnum.ResourceCategory; + } + Either categoryResult = elementOperation.getNewCategoryData(newCategory.getName(), NodeTypeEnum.ServiceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + StorageOperationStatus status = categoryResult.right().value(); + log.error("Cannot find category " + newCategory.getName() + " in the graph. status is " + status); + return status; + } + + CategoryData categoryData = categoryResult.left().value(); + Either createRelation = titanGenericDao.createRelation(componentData, categoryData, GraphEdgeLabels.CATEGORY, null); + log.debug("After associating category {} to component {}. Edge type is {}", categoryData, componentData.getUniqueId(), GraphEdgeLabels.CATEGORY); + if (createRelation.isRight()) { + log.error("Failed to associate category {} to component {}. Edge type is {}", categoryData, componentData.getUniqueId(), GraphEdgeLabels.CATEGORY); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation.right().value()); + return result; + } + + return result; + } + + private StorageOperationStatus moveLastModifierEdge(Component component, ComponentMetadataData componentData, UserData modifierUserData, NodeTypeEnum type) { + + StorageOperationStatus result = StorageOperationStatus.OK; + + GraphRelation lastModifierRelation = new GraphRelation(); + lastModifierRelation.setType(GraphEdgeLabels.LAST_MODIFIER.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(type, UniqueIdBuilder.getKeyByNodeType(type), component.getUniqueId()); + lastModifierRelation.setTo(relationEndPoint); + Either deleteIncomingRelation = titanGenericDao.deleteIncomingRelation(lastModifierRelation); + if (deleteIncomingRelation.isRight()) { + log.error("Failed to delete user from component {}. Edge type is {}", componentData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteIncomingRelation.right().value()); + return result; + } + + Either createRelation = titanGenericDao.createRelation(modifierUserData, componentData, GraphEdgeLabels.LAST_MODIFIER, null); + log.debug("After associating user {} to component {}. Edge type is {}", modifierUserData, componentData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + if (createRelation.isRight()) { + log.error("Failed to associate user {} to component {}. Edge type is {}", modifierUserData, componentData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation.right().value()); + return result; + } + return result; + } + + protected abstract ComponentMetadataData getMetaDataFromComponent(Component component); + + public abstract Either getComponent(String id, boolean inTransaction); + + public abstract Either getComponent(String id, ComponentParametersView componentParametersView, boolean inTrasnaction); + + // public abstract Either + // getComponent_tx(String id, boolean inTransaction); + + protected abstract Either getComponentByNameAndVersion(String name, String version, Map additionalParams, boolean inTransaction); + + public abstract Either getLightComponent(String id, boolean inTransaction); + + public abstract Either, StorageOperationStatus> getFilteredComponents(Map filters, boolean inTransaction); + + abstract Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData); + + abstract TitanOperationStatus setComponentCategoriesFromGraph(Component component); + + protected abstract Either getMetadataComponent(String id, boolean inTransaction); + + protected abstract Either updateComponent(T component, boolean inTransaction); + + protected abstract Either updateComponentFilterResult(T component, boolean inTransaction, ComponentParametersView filterParametersView); + + public abstract Either deleteComponent(String id, boolean inTransaction); + + public Either cloneComponent(T other, String version, boolean inTransaction) { + return cloneComponent(other, version, null, inTransaction); + } + + public abstract Either cloneComponent(T other, String version, LifecycleStateEnum targetLifecycle, boolean inTransaction); + + public abstract Component getDefaultComponent(); + + public abstract boolean isComponentExist(String componentId); + + public abstract Either validateComponentNameExists(String componentName); + + public abstract Either isComponentInUse(String componentId); + + protected Either isComponentInUse(String componentId, NodeTypeEnum nodeType) { + + Either relationByCriteria = titanGenericDao.getIncomingRelationByCriteria(new UniqueIdData(nodeType, componentId), GraphEdgeLabels.INSTANCE_OF, null); + if (relationByCriteria.isRight() && !relationByCriteria.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("failed to check relations for component node. id = {}, type = {}, error = {}", componentId, nodeType, relationByCriteria.right().value().name()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(relationByCriteria.right().value())); + } + + if (relationByCriteria.isLeft()) { + // component is in use + return Either.left(true); + } else { + return Either.left(false); + } + + } + + public abstract Either, StorageOperationStatus> getAllComponentsMarkedForDeletion(); + + protected Either, StorageOperationStatus> getAllComponentsMarkedForDeletion(NodeTypeEnum nodeType) { + + List componentIdsToDelete = new ArrayList(); + // get all components marked for delete + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), true); + + Either, TitanOperationStatus> componentsToDelete = titanGenericDao.getByCriteria(nodeType, props, ComponentMetadataData.class); + + if (componentsToDelete.isRight()) { + TitanOperationStatus error = componentsToDelete.right().value(); + if (error.equals(TitanOperationStatus.NOT_FOUND)) { + log.trace("no components to delete"); + return Either.left(componentIdsToDelete); + } else { + log.info("failed to find components to delete. error : {}", error.name()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error)); + } + + } + for (ComponentMetadataData resourceData : componentsToDelete.left().value()) { + componentIdsToDelete.add(resourceData.getMetadataDataDefinition().getUniqueId()); + } + return Either.left(componentIdsToDelete); + } + + protected Either, TitanOperationStatus> __getLastVersion(NodeTypeEnum type, Map props, Class clazz) { + try { + + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(graph.right().value()); + } + + TitanGraph tGraph = graph.left().value(); + TitanGraphQuery query = tGraph.query(); + query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); + + if (props != null && !props.isEmpty()) { + for (Map.Entry entry : props.entrySet()) { + query = query.hasNot(entry.getKey(), entry.getValue()); + } + } + query.has(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Iterable vertices = query.vertices(); + + if (vertices == null) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + Iterator iterator = vertices.iterator(); + List result = new ArrayList(); + + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + Map newProp = titanGenericDao.getProperties(vertex); + T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); + result.add(element); + } + if (result.size() == 0) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + log.debug("No nodes in graph for criteria : from type = {} and properties = {}", type, props); + return Either.left(result); + } catch (Exception e) { + log.debug("Failed get by criteria for type = {} and properties = {}. {}", type, props, e); + return Either.right(TitanGraphClient.handleTitanException(e)); + } + } + + protected Either, TitanOperationStatus> getLastVersion(NodeTypeEnum type, Map hasNotProps, Class clazz) { + return getLastVersion(type, null, hasNotProps, clazz); + } + + protected Either, TitanOperationStatus> getLastVersion(NodeTypeEnum type, Map hasProps, Map hasNotProps, Class clazz) { + + Map props = new HashMap<>(); + + if (hasProps != null) { + props.putAll(hasProps); + } + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either, TitanOperationStatus> byCriteria = titanGenericDao.getByCriteria(type, props, hasNotProps, clazz); + + return byCriteria; + + } + + public Either, StorageOperationStatus> getComponentCatalogData(NodeTypeEnum type, Map propertiesToMatch, Class clazz1, Class clazz2, boolean inTransaction) { + log.debug("Start getComponentCatalogData for type: {}", type.name()); + Set result = new HashSet(); + Either, TitanOperationStatus> lastVersionNodes = getLastVersion(type, propertiesToMatch, clazz2); + Either, StorageOperationStatus> last = retrieveComponentsFromNodes(lastVersionNodes, inTransaction); + if (last.isLeft() && last.left().value() != null) { + result.addAll(last.left().value()); + } + if (type == NodeTypeEnum.Resource) { + propertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), false); + } + Either, TitanOperationStatus> componentsNodes = titanGenericDao.getByCriteria(type, propertiesToMatch, clazz2); + Either, StorageOperationStatus> certified = retrieveComponentsFromNodes(componentsNodes, inTransaction); + if (certified.isLeft() && certified.left().value() != null) { + result.addAll(certified.left().value()); + } + return Either.left(result); + + } + + protected Either, StorageOperationStatus> retrieveComponentsFromNodes(Either, TitanOperationStatus> componentsNodes, boolean inTransaction) { + Set result = new HashSet(); + if (componentsNodes.isRight()) { + // in case of NOT_FOUND from Titan client return to UI empty list + if (componentsNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("No components were found"); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(componentsNodes.right().value())); + } + } else { + List componentDataList = componentsNodes.left().value(); + for (S componentData : componentDataList) { + // Either component = + // getComponent((String) componentData.getUniqueId(), + // inTransaction); + Either component = getLightComponent((String) componentData.getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get component for id = {} error : {} skip resource", componentData.getUniqueId(), component.right().value()); + // return Either.right(service.right().value()); + } else { + result.add(component.left().value()); + } + } + } + return Either.left(result); + } + + protected StorageOperationStatus removeArtifactsFromComponent(Component component, NodeTypeEnum componentType) { + + String componentId = component.getUniqueId(); + // Map artifacts = component.getArtifacts(); + Either, StorageOperationStatus> artifactsRes = artifactOperation.getArtifacts(componentId, componentType, true); + if (artifactsRes.isRight() && !artifactsRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + return artifactsRes.right().value(); + } + if (artifactsRes.isLeft() && artifactsRes.left().value() != null) { + Map artifacts = artifactsRes.left().value(); + for (Entry entry : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + Either removeArifactFromResource = artifactOperation.removeArifactFromResource(componentId, artifactDefinition.getUniqueId(), componentType, true, true); + if (removeArifactFromResource.isRight()) { + return removeArifactFromResource.right().value(); + } + } + } + return StorageOperationStatus.OK; + } + + public Either, StorageOperationStatus> getTesterFollowedComponent(String userId, Set lifecycleStates, boolean inTransaction, NodeTypeEnum neededType) { + List resList = new ArrayList<>(); + Either, StorageOperationStatus> rip = getFollowedComponent(userId, lifecycleStates, null, inTransaction, titanGenericDao, neededType); + if (rip.isLeft()) { + List ripRes = rip.left().value(); + if (ripRes != null && !ripRes.isEmpty()) { + resList.addAll(ripRes); + } + Set rfcState = new HashSet<>(); + rfcState.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either, StorageOperationStatus> rfc = getFollowedComponent(null, rfcState, null, inTransaction, titanGenericDao, neededType); + if (rfc.isLeft()) { + List rfcRes = rfc.left().value(); + if (rfcRes != null && !rfcRes.isEmpty()) { + resList.addAll(rfcRes); + } + } else { + return Either.right(rfc.right().value()); + } + + } else { + return Either.right(rip.right().value()); + } + return Either.left(resList); + + } + + /** + * generate UUID only for case that version is "XX.01" - (start new version) + * + * @param component + */ + protected void generateUUID(Component component) { + String version = component.getVersion(); + if (uuidNewVersion.matcher(version).matches()) { + UUID uuid = UUID.randomUUID(); + component.getComponentMetadataDefinition().getMetadataDataDefinition().setUUID(uuid.toString()); + MDC.put("serviceInstanceID", uuid.toString()); + } + } + + protected Either, TitanOperationStatus> getVersionList(NodeTypeEnum type, String version, Component component, Class clazz) { + return getVersionList(type, version, component.getUUID(), component.getSystemName(), clazz); + } + + protected Either, TitanOperationStatus> getVersionList(NodeTypeEnum type, String version, String uuid, String systemName, Class clazz) { + Map props = new HashMap(); + Map hasNotProps = new HashMap(); + + if (version.startsWith("0")) { + props.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + } else { + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + } + hasNotProps.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), true); + Either, TitanOperationStatus> result = titanGenericDao.getByCriteria(type, props, hasNotProps, clazz); + + Map versionMap = new HashMap(); + if (result.isRight()) { + if (!result.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.right(result.right().value()); + } + + } else { + switch (type) { + case Resource: + List components = (List) result.left().value(); + for (ResourceMetadataData data : components) { + versionMap.put(data.getMetadataDataDefinition().getVersion(), (String) data.getUniqueId()); + } + break; + case Service: + List componentsS = (List) result.left().value(); + for (ServiceMetadataData data : componentsS) { + versionMap.put(data.getMetadataDataDefinition().getVersion(), (String) data.getUniqueId()); + } + break; + case Product: + List componentsP = (List) result.left().value(); + for (ProductMetadataData data : componentsP) { + versionMap.put(data.getMetadataDataDefinition().getVersion(), (String) data.getUniqueId()); + } + default: + break; + } + } + + return Either.left(versionMap); + } + + protected StorageOperationStatus deleteAdditionalInformation(NodeTypeEnum nodeType, String componentId) { + + Either deleteRes = additionalInformationOperation.deleteAllAdditionalInformationParameters(nodeType, componentId, true); + + if (deleteRes.isRight()) { + StorageOperationStatus status = deleteRes.right().value(); + return status; + } + + return StorageOperationStatus.OK; + + } + + protected StorageOperationStatus addAdditionalInformation(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition informationDefinition) { + + Either status = additionalInformationOperation.addAdditionalInformationNode(nodeType, componentId, informationDefinition); + + if (status.isRight()) { + TitanOperationStatus titanStatus = status.right().value(); + return DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + + log.trace("After adding additional information to component {}. Result is {}", componentId, status.left().value()); + + return StorageOperationStatus.OK; + + } + + protected StorageOperationStatus addAdditionalInformation(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition informationDefinition, TitanVertex metadataVertex) { + + TitanOperationStatus status = additionalInformationOperation.addAdditionalInformationNode(nodeType, componentId, informationDefinition, metadataVertex); + log.trace("After adding additional information to component {}. Result is {}", componentId, status); + + if (!status.equals(TitanOperationStatus.OK)) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + + return StorageOperationStatus.OK; + + } + + public Either, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType, boolean inTransacton) { + List artifacts = new ArrayList(); + Either, StorageOperationStatus> artifactsResponse = artifactOperation.getArtifacts(parentId, parentType, inTransacton); + if (artifactsResponse.isRight()) { + if (!artifactsResponse.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + log.debug("failed to retrieve artifacts for {} {}", parentType, parentId); + return Either.right(artifactsResponse.right().value()); + } + } else { + artifacts.addAll(artifactsResponse.left().value().values()); + } + + if (NodeTypeEnum.Resource.equals(parentType)) { + Either, StorageOperationStatus> interfacesArtifactsForResource = getAdditionalArtifacts(parentId, false, true); + if (artifactsResponse.isRight() && !interfacesArtifactsForResource.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + log.debug("failed to retrieve interface artifacts for {} {}", parentType, parentId); + return Either.right(interfacesArtifactsForResource.right().value()); + } else if (artifactsResponse.isLeft()) { + artifacts.addAll(interfacesArtifactsForResource.left().value()); + } + } + return Either.left(artifacts); + } + + protected void addComponentInternalFields(ComponentMetadataData componentMetadataData) { + org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition metadataDataDefinition = componentMetadataData.getMetadataDataDefinition(); + Long creationDate = metadataDataDefinition.getCreationDate(); + + long currentDate = System.currentTimeMillis(); + if (creationDate == null) { + metadataDataDefinition.setCreationDate(currentDate); + } + metadataDataDefinition.setLastUpdateDate(currentDate); + + String lifecycleStateEnum = metadataDataDefinition.getState(); + if (lifecycleStateEnum == null) { + metadataDataDefinition.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + } + String componentUniqueId = UniqueIdBuilder.buildComponentUniqueId(); + metadataDataDefinition.setUniqueId(componentUniqueId); + metadataDataDefinition.setHighestVersion(true); + } + + protected StorageOperationStatus createTagsForComponent(Component component) { + List tags = component.getTags(); + if (tags != null && false == tags.isEmpty()) { + Either, StorageOperationStatus> tagsResult = createNewTagsList(tags); + + if (tagsResult == null) { + log.debug("tagsResult is null"); + return StorageOperationStatus.GENERAL_ERROR; + } + if (tagsResult.isRight()) { + return tagsResult.right().value(); + } + List tagsToCreate = tagsResult.left().value(); + return createTagNodesOnGraph(tagsToCreate); + } + log.trace("All tags created succesfully for component {}", component.getUniqueId()); + return StorageOperationStatus.OK; + } + + protected Either, StorageOperationStatus> findGroupingsForComponent(NodeTypeEnum nodeTypeEnum, Component component) { + List categories = component.getCategories(); + List groupingDataToAssociate = new ArrayList<>(); + if (categories != null) { + groupingDataToAssociate = new ArrayList<>(); + for (CategoryDefinition categoryDefinition : categories) { + List subcategories = categoryDefinition.getSubcategories(); + if (subcategories != null) { + for (SubCategoryDefinition subCategoryDefinition : subcategories) { + List groupingDataDefinitions = subCategoryDefinition.getGroupings(); + if (groupingDataDefinitions != null) { + for (GroupingDataDefinition grouping : groupingDataDefinitions) { + String groupingId = grouping.getUniqueId(); + Either findGroupingEither = findGrouping(nodeTypeEnum, groupingId); + if (findGroupingEither.isRight()) { + TitanOperationStatus status = findGroupingEither.right().value(); + log.error("Cannot find grouping {} in the graph. status is {}", groupingId, status); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + groupingDataToAssociate.add(findGroupingEither.left().value()); + } + } + } + } + } + } + } + return Either.left(groupingDataToAssociate); + } + + protected TitanOperationStatus associateGroupingsToComponent(ComponentMetadataData componentMetadataData, List groupingDataToAssociate) { + for (GroupingData groupingData : groupingDataToAssociate) { + GraphEdgeLabels groupingLabel = GraphEdgeLabels.GROUPING; + Either result = titanGenericDao.createRelation(componentMetadataData, groupingData, groupingLabel, null); + log.debug("After associating grouping {} to component {}. Edge type is {}", groupingData, componentMetadataData, groupingLabel); + if (result.isRight()) { + return result.right().value(); + } + } + log.trace("All groupings associated succesfully to component {}", componentMetadataData); + return TitanOperationStatus.OK; + } + + public abstract Either increaseAndGetComponentInstanceCounter(String componentId, boolean inTransaction); + + protected Either increaseAndGetComponentInstanceCounter(String componentId, NodeTypeEnum nodeType, boolean inTransaction) { + Either result = null; + try { + + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + Either vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of component metadata, nodeType:{} , id: {}", nodeType, componentId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value())); + return result; + } + Vertex vertex = vertexService.left().value(); + Integer instanceCounter = vertex.value(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty()); + ++instanceCounter; + vertex.property(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty(), instanceCounter); + result = Either.left(instanceCounter); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("increaseAndGetComponentInstanceCounter operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("increaseAndGetComponentInstanceCounter operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + protected Either setComponentInstanceCounter(String componentId, NodeTypeEnum nodeType, int counter, boolean inTransaction) { + Either result = null; + try { + + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + Either vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of component metadata ofor id = {}", componentId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value())); + return result; + } + Vertex vertex = vertexService.left().value(); + vertex.property(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty(), counter); + result = Either.left(counter); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("deleteService operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("deleteService operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + protected TitanOperationStatus setComponentInstancesFromGraph(String uniqueId, Component component, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType) { + + Either, List>, TitanOperationStatus> resourceInstancesOfService = componentInstanceOperation.getComponentInstancesOfComponent(uniqueId, containerNodeType, compInstNodeType); + + if (resourceInstancesOfService.isRight()) { + TitanOperationStatus status = resourceInstancesOfService.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } else { + log.error("Failed to fetch resource instances and their relations. status is {}", status); + } + return status; + } + + ImmutablePair, List> immutablePair = resourceInstancesOfService.left().value(); + List instances = immutablePair.getKey(); + List relations = immutablePair.getValue(); + + component.setComponentInstances(instances); + component.setComponentInstancesRelations(relations); + + return TitanOperationStatus.OK; + } + + /** + * set all properties of all of its resources + * + * @param uniqueId + * @return + */ + protected TitanOperationStatus ___setComponentInstancesPropertiesFromGraph(String uniqueId, Component component) { + + List resourceInstances = component.getComponentInstances(); + + Map> resourceInstancesProperties = new HashMap<>(); + + Map> alreadyProcessedResources = new HashMap<>(); + + if (resourceInstances != null) { + for (ComponentInstance resourceInstance : resourceInstances) { + + log.debug("Going to update properties of resource instance {}", resourceInstance.getUniqueId()); + String resourceUid = resourceInstance.getComponentUid(); + + List properties = alreadyProcessedResources.get(resourceUid); + if (properties == null) { + properties = new ArrayList<>(); + TitanOperationStatus findAllRes = propertyOperation.findAllResourcePropertiesRecursively(resourceUid, properties); + if (findAllRes != TitanOperationStatus.OK) { + return findAllRes; + } + alreadyProcessedResources.put(resourceUid, properties); + } + log.debug("After getting properties of resource {}. Number of properties is {}", resourceUid, (properties == null ? 0 : properties.size())); + if (false == properties.isEmpty()) { + + String resourceInstanceUid = resourceInstance.getUniqueId(); + + Either, TitanOperationStatus> propertyValuesRes = propertyOperation.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid); + log.debug("After fetching property under resource instance {}", resourceInstanceUid); + if (propertyValuesRes.isRight()) { + TitanOperationStatus status = propertyValuesRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return status; + } + } + + Map propertyIdToValue = new HashMap<>(); + populateMapperWithPropertyValues(propertyValuesRes, propertyIdToValue); + + List resourceInstancePropertyList = new ArrayList<>(); + for (PropertyDefinition propertyDefinition : properties) { + + String defaultValue = propertyDefinition.getDefaultValue(); + String value = defaultValue; + String valueUid = null; + + String propertyId = propertyDefinition.getUniqueId(); + ComponentInstanceProperty valuedProperty = propertyIdToValue.get(propertyId); + if (valuedProperty != null) { + String newValue = valuedProperty.getValue(); + // if (newValue != null) { + value = newValue; + // } + + valueUid = valuedProperty.getValueUniqueUid(); + log.trace("Found value {} under resource instance whice override the default value {}", value, defaultValue); + } + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(propertyDefinition, value, valueUid); + + // TODO: currently ignore constraints since they are not + // inuse and cause to error in convertion to object. + resourceInstanceProperty.setConstraints(null); + + resourceInstancePropertyList.add(resourceInstanceProperty); + + } + + resourceInstancesProperties.put(resourceInstanceUid, resourceInstancePropertyList); + } + + } + + component.setComponentInstancesProperties(resourceInstancesProperties); + } + + return TitanOperationStatus.OK; + } + + private void populateMapperWithPropertyValues(Either, TitanOperationStatus> propertyValuesRes, Map propertyIdToValue) { + + if (propertyValuesRes.isLeft()) { + List resourceInstanceValues = propertyValuesRes.left().value(); + if (resourceInstanceValues != null) { + for (ComponentInstanceProperty resourceInstanceProperty : resourceInstanceValues) { + propertyIdToValue.put(resourceInstanceProperty.getUniqueId(), resourceInstanceProperty); + } + } + } + } + + public abstract Either, StorageOperationStatus> getAdditionalArtifacts(String resourceId, boolean recursively, boolean inTransaction); + + protected abstract StorageOperationStatus validateCategories(Component currentComponent, Component component, ComponentMetadataData componentData, NodeTypeEnum type); + + protected abstract StorageOperationStatus updateDerived(Component component, Component currentComponent, ComponentMetadataData updatedResourceData, Class clazz); + + public abstract Either markComponentToDelete(Component componentToDelete, boolean inTransaction); + + protected Either internalMarkComponentToDelete(Component componentToDelete, boolean inTransaction) { + Either result = null; + + if ((componentToDelete.getIsDeleted() != null) && componentToDelete.getIsDeleted() && !componentToDelete.isHighestVersion()) { + // component already marked for delete + result = Either.left(componentToDelete); + return result; + } else { + + ComponentMetadataData componentMetaData = getMetaDataFromComponent(componentToDelete); + + componentMetaData.getMetadataDataDefinition().setIsDeleted(true); + componentMetaData.getMetadataDataDefinition().setHighestVersion(false); + componentMetaData.getMetadataDataDefinition().setLastUpdateDate(System.currentTimeMillis()); + try { + Either updateNode = titanGenericDao.updateNode(componentMetaData, ComponentMetadataData.class); + + StorageOperationStatus updateComponent; + if (updateNode.isRight()) { + log.debug("Failed to update component {}. Status is {}", componentMetaData.getUniqueId(), updateNode.right().value()); + updateComponent = DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()); + result = Either.right(updateComponent); + return result; + } + + result = Either.left(componentToDelete); + return result; + } finally { + + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("updateResource operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("updateResource operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + + } + } + } + + private Either, TitanOperationStatus> convertReqDataListToReqDefList(ComponentInstance componentInstance, List> requirementData) { + ConvertDataToDef convertor = (data, edge) -> convertReqDataToReqDef(data, edge); + AddOwnerData dataAdder = (reqDef, compInstance) -> addOwnerDataReq(reqDef, compInstance); + + return convertDataToDefinition(componentInstance, requirementData, convertor, dataAdder); + } + + private Either, TitanOperationStatus> convertCapDataListToCapDefList(ComponentInstance componentInstance, List> capabilityData) { + ConvertDataToDef convertor = (data, edge) -> convertCapDataToCapDef(data, edge); + AddOwnerData dataAdder = (capDef, compInstance) -> addOwnerDataCap(capDef, compInstance); + Either, TitanOperationStatus> convertationResult = convertDataToDefinition(componentInstance, capabilityData, convertor, dataAdder); + if (convertationResult.isLeft()) { + convertationResult = componentInstanceOperation.updateCapDefPropertyValues(componentInstance, convertationResult.left().value()); + } + return convertationResult; + } + + private Either convertCapDataToCapDef(CapabilityData data, GraphEdge edge) { + Either eitherDef = capabilityOperation.getCapabilityByCapabilityData(data); + + if (eitherDef.isLeft()) { + CapabilityDefinition capDef = eitherDef.left().value(); + Map properties = edge.getProperties(); + if (properties != null) { + String name = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + String source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + List sourcesList = new ArrayList(); + capabilityOperation.getCapabilitySourcesList(source, sourcesList); + capDef.setName(name); + capDef.setCapabilitySources(sourcesList); + + String requiredOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + if (requiredOccurrences != null) { + capDef.setMinOccurrences(requiredOccurrences); + } + String leftOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null) { + capDef.setMaxOccurrences(leftOccurrences); + } + + } + eitherDef = Either.left(capDef); + } + return eitherDef; + } + + private Either convertReqDataToReqDef(RequirementData data, GraphEdge edge) { + Either eitherDef = requirementOperation.getRequirement(data.getUniqueId()); + + if (eitherDef.isLeft()) { + RequirementDefinition requirementDef = eitherDef.left().value(); + Map properties = edge.getProperties(); + if (properties != null) { + String name = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + requirementDef.setName(name); + String requiredOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + if (requiredOccurrences != null) { + requirementDef.setMinOccurrences(requiredOccurrences); + } + String leftOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null) { + requirementDef.setMaxOccurrences(leftOccurrences); + } + } + eitherDef = Either.left(requirementDef); + } + return eitherDef; + } + + private Either, TitanOperationStatus> convertDataToDefinition(ComponentInstance componentInstance, List> requirementData, ConvertDataToDef convertor, AddOwnerData dataAdder) { + Either, TitanOperationStatus> eitherResult; + // Convert Data To Definition + Stream> reqDefStream = requirementData.stream().map(e -> convertor.convert(e.left, e.right)); + + // Collect But Stop After First Error + List> filteredReqDefList = StreamUtils.takeWhilePlusOne(reqDefStream, p -> p.isLeft()).collect(Collectors.toList()); + Optional> optionalError = filteredReqDefList.stream().filter(p -> p.isRight()).findAny(); + if (optionalError.isPresent()) { + eitherResult = Either.right(optionalError.get().right().value()); + } else { + // Convert From Either To Definition And Collect + List reqDefList = filteredReqDefList.stream().map(e -> e.left().value()).collect(Collectors.toList()); + // Add Owner Data + reqDefList.forEach(e -> dataAdder.addData(e, componentInstance)); + eitherResult = Either.left(reqDefList); + } + + return eitherResult; + } + + interface ConvertDataToDef { + Either convert(Data d, GraphEdge edge); + } + + interface AddOwnerData { + void addData(Def def, ComponentInstance compInstance); + } + + private void addOwnerDataCap(CapabilityDefinition capDef, ComponentInstance componentInstance) { + capDef.setOwnerId(componentInstance.getUniqueId()); + capDef.setOwnerName(componentInstance.getName()); + } + + private void addOwnerDataReq(RequirementDefinition reqDef, ComponentInstance componentInstance) { + reqDef.setOwnerId(componentInstance.getUniqueId()); + reqDef.setOwnerName(componentInstance.getName()); + } + + public Either>, TitanOperationStatus> getRequirements(Component component, NodeTypeEnum nodeTypeEnum, boolean inTransaction) { + final HashMap> emptyMap = new HashMap<>(); + Either>, TitanOperationStatus> eitherResult = Either.left(emptyMap); + try { + List componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + Function>, TitanOperationStatus>> dataCollector = e -> componentInstanceOperation.getRequirements(e, nodeTypeEnum); + Either>, TitanOperationStatus>>>, TitanOperationStatus> eitherDataCollected = collectDataFromComponentsInstances(componentInstances, + dataCollector); + if (eitherDataCollected.isRight()) { + eitherResult = Either.right(eitherDataCollected.right().value()); + } else { + // Converts Data to Def stop if encountered conversion error + DataDefConvertor someConvertor = (e1, e2) -> convertReqDataListToReqDefList(e1, e2); + Either>, TitanOperationStatus> fullDefList = convertDataToDefComponentLevel(eitherDataCollected.left().value(), someConvertor); + if (fullDefList.isRight()) { + eitherResult = Either.right(fullDefList.right().value()); + } else { + Stream defStream = fullDefList.left().value().stream().flatMap(e -> e.stream()); + // Collect to Map and using grouping by + Map> capTypeCapListMap = defStream.collect(Collectors.groupingBy(e -> e.getCapability())); + eitherResult = Either.left(capTypeCapListMap); + } + + } + + } + } finally { + if (inTransaction == false) { + titanGenericDao.commit(); + } + } + + return eitherResult; + } + + public Either>, TitanOperationStatus> getCapabilities(Component component, NodeTypeEnum nodeTypeEnum, boolean inTransaction) { + final HashMap> emptyMap = new HashMap<>(); + Either>, TitanOperationStatus> eitherResult = Either.left(emptyMap); + try { + List componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + Function>, TitanOperationStatus>> dataCollector = e -> componentInstanceOperation.getCapabilities(e, nodeTypeEnum); + Either>, TitanOperationStatus>>>, TitanOperationStatus> eitherDataCollected = collectDataFromComponentsInstances(componentInstances, + dataCollector); + if (eitherDataCollected.isRight()) { + eitherResult = Either.right(eitherDataCollected.right().value()); + } else { + // Converts CapData to CapDef removes stop if encountered + // conversion error + DataDefConvertor someConvertor = (e1, e2) -> convertCapDataListToCapDefList(e1, e2); + Either>, TitanOperationStatus> fullDefList = convertDataToDefComponentLevel(eitherDataCollected.left().value(), someConvertor); + if (fullDefList.isRight()) { + eitherResult = Either.right(fullDefList.right().value()); + } else { + Stream defStream = fullDefList.left().value().stream().flatMap(e -> e.stream()); + // Collect to Map grouping by Type + Map> capTypeCapListMap = defStream.collect(Collectors.groupingBy(e -> e.getType())); + eitherResult = Either.left(capTypeCapListMap); + } + + } + + } + } finally { + if (inTransaction == false) { + titanGenericDao.commit(); + } + } + + return eitherResult; + } + + public Either>, TitanOperationStatus>>>, TitanOperationStatus> collectDataFromComponentsInstances(List componentInstances, + Function>, TitanOperationStatus>> dataGetter) { + Either>, TitanOperationStatus>>>, TitanOperationStatus> eitherResult; + + // Get List of Each componentInstance and it's Capabilities Data + Stream>, TitanOperationStatus>>> ownerDataStream = componentInstances.stream().map(element -> new ImmutablePair<>(element, dataGetter.apply(element))); + // Collect but stop after first error + List>, TitanOperationStatus>>> ownerCapDataList = StreamUtils + .takeWhilePlusOne(ownerDataStream, p -> p.right.isLeft() || p.right.isRight() && p.right.right().value() == TitanOperationStatus.NOT_FOUND).collect(Collectors.toList()); + + Optional>, TitanOperationStatus>>> optionalError = ownerCapDataList.stream() + .filter(p -> p.right.isRight() && p.right.right().value() != TitanOperationStatus.NOT_FOUND).findAny(); + if (optionalError.isPresent()) { + eitherResult = Either.right(optionalError.get().right.right().value()); + } else { + eitherResult = Either.left(ownerCapDataList.stream().filter(p -> p.right.isLeft()).collect(Collectors.toList())); + } + + return eitherResult; + } + + interface DataDefConvertor { + Either, TitanOperationStatus> convertDataToDefComponentInstance(ComponentInstance componentInstance, List> data); + } + + public Either>, TitanOperationStatus> convertDataToDefComponentLevel(List>, TitanOperationStatus>>> ownerCapDataList, + DataDefConvertor convertor) { + // Converts CapData to CapDef removes stop if encountered conversion + // error + TitanOperationStatus error = null; + List> defList = new ArrayList<>(); + for (int i = 0; i < ownerCapDataList.size(); i++) { + ImmutablePair>, TitanOperationStatus>> immutablePair = ownerCapDataList.get(i); + Either, TitanOperationStatus> convertCapDataListToCapDefList = convertor.convertDataToDefComponentInstance(immutablePair.left, immutablePair.right.left().value()); + if (convertCapDataListToCapDefList.isRight()) { + error = convertCapDataListToCapDefList.right().value(); + break; + } else { + defList.add(convertCapDataListToCapDefList.left().value()); + } + + } + Either>, TitanOperationStatus> eitherResult = (error != null) ? Either.right(error) : Either.left(defList); + return eitherResult; + + } + + private Map findLatestVersion(List resourceDataList) { + Map, ComponentMetadataData> latestVersionMap = new HashMap, ComponentMetadataData>(); + for (ComponentMetadataData resourceData : resourceDataList) { + ComponentMetadataData latestVersionData = resourceData; + + ComponentMetadataDataDefinition metadataDataDefinition = resourceData.getMetadataDataDefinition(); + Pair pair = createKeyPair(latestVersionData); + if (latestVersionMap.containsKey(pair)) { + latestVersionData = latestVersionMap.get(pair); + String currentVersion = latestVersionData.getMetadataDataDefinition().getVersion(); + String newVersion = metadataDataDefinition.getVersion(); + if (CommonBeUtils.compareAsdcComponentVersions(newVersion, currentVersion)) { + latestVersionData = resourceData; + } + } + if (log.isDebugEnabled()) + log.debug("last certified version of resource = {} version is {}", latestVersionData.getMetadataDataDefinition().getName(), latestVersionData.getMetadataDataDefinition().getVersion()); + + latestVersionMap.put(pair, latestVersionData); + } + + Map resVersionMap = new HashMap(); + for (ComponentMetadataData resourceData : latestVersionMap.values()) { + ComponentMetadataData latestVersionData = resourceData; + ComponentMetadataDataDefinition metadataDataDefinition = resourceData.getMetadataDataDefinition(); + if (resVersionMap.containsKey(metadataDataDefinition.getUUID())) { + latestVersionData = resVersionMap.get(metadataDataDefinition.getUUID()); + String currentVersion = latestVersionData.getMetadataDataDefinition().getVersion(); + String newVersion = metadataDataDefinition.getVersion(); + if (CommonBeUtils.compareAsdcComponentVersions(newVersion, currentVersion)) { + latestVersionData = resourceData; + } + } + if (log.isDebugEnabled()) + log.debug("last uuid version of resource = {} version is {}", latestVersionData.getMetadataDataDefinition().getName(), latestVersionData.getMetadataDataDefinition().getVersion()); + resVersionMap.put(latestVersionData.getMetadataDataDefinition().getUUID(), latestVersionData); + } + + return resVersionMap; + } + + private Pair createKeyPair(ComponentMetadataData metadataData) { + Pair pair = null; + NodeTypeEnum label = NodeTypeEnum.getByName(metadataData.getLabel()); + switch (label) { + case Resource: + pair = new ImmutablePair(metadataData.getMetadataDataDefinition().getName(), ((ResourceMetadataDataDefinition) metadataData.getMetadataDataDefinition()).getResourceType().getValue()); + break; + default: + pair = new ImmutablePair(metadataData.getMetadataDataDefinition().getName(), metadataData.getLabel()); + break; + } + + return pair; + } + + public Either, StorageOperationStatus> getLatestVersionNotAbstractComponentsMetadataOnly(boolean isAbstract, Boolean isHighest, ComponentTypeEnum componentTypeEnum, String internalComponentType) { + try { + + // Map hasPpropertiesToMatch = new HashMap<>(); + // Map hasNotPpropertiesToMatch = new HashMap<>(); + List> properties = new ArrayList<>(); + if (componentTypeEnum.equals(ComponentTypeEnum.RESOURCE)) { + // hasPpropertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), + // isAbstract); + properties.add(new ImmutableTriple<>(QueryType.HAS, GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), isAbstract)); + + if (internalComponentType != null) { + switch (internalComponentType.toLowerCase()) { + case "vf": + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name())); + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VL.name())); + // hasNotPpropertiesToMatch.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), + // ResourceTypeEnum.VF.name()); + break; + case "service": + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VFC.name())); + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VL.name())); + // hasNotPpropertiesToMatch.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), + // ResourceTypeEnum.VFC.name()); + break; + case "vl": + properties.add(new ImmutableTriple<>(QueryType.HAS, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VL.name())); + // hasPpropertiesToMatch.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), + // ResourceTypeEnum.VL.name()); + break; + default: + break; + } + } + } + // hasNotPpropertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())); + // hasNotPpropertiesToMatch.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), + // true); + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.IS_DELETED.getProperty(), true)); + // Either, TitanOperationStatus> + // resourceNodes = titanGenericDao.getByCriteria( + // componentTypeEnum.getNodeType(), hasPpropertiesToMatch, + // hasNotPpropertiesToMatch, + // ComponentMetadataData.class); + Either, TitanOperationStatus> resourceNodes = titanGenericDao.getByCriteria(componentTypeEnum.getNodeType(), ComponentMetadataData.class, properties); + if (resourceNodes.isRight()) { + // in case of NOT_FOUND from Titan client return to UI empty + // list + if (resourceNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.left(new ArrayList<>()); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceNodes.right().value())); + } + } else { + List resourceDataList = resourceNodes.left().value(); + Collection resCollection = resourceDataList; + if (isHighest != null && isHighest) { + Map latestVersionListMap = findLatestVersion(resourceDataList); + resCollection = latestVersionListMap.values(); + } + return Either.left(resCollection); + } + } finally { + titanGenericDao.commit(); + } + + } + + public Either, StorageOperationStatus> getLatestVersionNotAbstractComponents(boolean isAbstract, Boolean isHighest, ComponentTypeEnum componentTypeEnum, String internalComponentType, List componentUids) { + try { + List result = new ArrayList<>(); + Map componentUidsMap = new HashMap<>(); + if (componentUids == null) { + Either, StorageOperationStatus> resourceNodes = getLatestVersionNotAbstractComponentsMetadataOnly(isAbstract, isHighest, componentTypeEnum, internalComponentType); + if (resourceNodes.isRight()) { + return Either.right(resourceNodes.right().value()); + } + Collection collection = resourceNodes.left().value(); + + if (collection == null) { + componentUids = new ArrayList<>(); + } else { + componentUids = collection.stream().map(p -> p.getMetadataDataDefinition().getUniqueId()).collect(Collectors.toList()); + // collection.forEach(p -> { + // if (NodeTypeEnum.Resource.getName().equals(p.getLabel())) + // { + // componentUidsMap.put(p.getMetadataDataDefinition().getUniqueId(), + // ((ResourceMetadataDataDefinition) + // p.getMetadataDataDefinition()).getResourceType()); + // } + // }); + + } + + } + if (false == componentUids.isEmpty()) { + + Manager manager = new Manager(); + int numberOfWorkers = 5; + + manager.init(numberOfWorkers); + for (String componentUid : componentUids) { + ComponentParametersView componentParametersView = buildComponentViewForNotAbstract(); + // ResourceTypeEnum type = + // componentUidsMap.get(componentUid); + // if (type != null && ResourceTypeEnum.VL.equals(type)) { + if (internalComponentType != null && "vl".equalsIgnoreCase(internalComponentType)) { + componentParametersView.setIgnoreCapabilities(false); + componentParametersView.setIgnoreRequirements(false); + } + manager.addJob(new Job() { + @Override + public Either doWork() { + // long start = System.currentTimeMillis(); + Either component = getComponent(componentUid, componentParametersView, false); + // long stop = System.currentTimeMillis(); + // log.info("********** Time calculation in ms: + // getComponent single {}", (stop-start)); + return component; + } + }); + } + LinkedBlockingQueue> res = manager.start(); + + for (Either resource : res) { + if (resource == null) { + if (log.isDebugEnabled()) + log.debug("Failed to fetch resource returned null "); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + if (resource.isRight()) { + if (log.isDebugEnabled()) + log.debug("Failed to fetch resource for error is {}", resource.right().value()); + return Either.right(resource.right().value()); + } + Component component = resource.left().value(); + component.setContactId(null); + component.setCreationDate(null); + component.setCreatorUserId(null); + component.setCreatorFullName(null); + component.setLastUpdateDate(null); + component.setLastUpdaterUserId(null); + component.setLastUpdaterFullName(null); + component.setNormalizedName(null); + result.add(resource.left().value()); + } + + if (componentUids.size() != result.size()) { + if (log.isDebugEnabled()) + log.debug("one of the workers failed to complete job "); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + + return Either.left(result); + + } finally { + titanGenericDao.commit(); + } + } + + private ComponentParametersView buildComponentViewForNotAbstract() { + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + // componentParametersView.setIgnoreRequirements(false); + // componentParametersView.setIgnoreCapabilities(false); + componentParametersView.setIgnoreCategories(false); + componentParametersView.setIgnoreAllVersions(false); + componentParametersView.setIgnoreAllVersions(false); + return componentParametersView; + } + + protected TitanOperationStatus setCapabilitiesFromGraph(String uniqueId, Component component, NodeTypeEnum nodeType) { + TitanOperationStatus titanStatus; + Either>, TitanOperationStatus> eitherCapabilities = getCapabilities(component, nodeType, true); + if (eitherCapabilities.isLeft()) { + titanStatus = TitanOperationStatus.OK; + Map> capabilities = eitherCapabilities.left().value(); + if (capabilities != null && !capabilities.isEmpty()) { + component.setCapabilities(capabilities); + } + } else { + titanStatus = eitherCapabilities.right().value(); + } + return titanStatus; + } + + protected TitanOperationStatus setRequirementsFromGraph(String uniqueId, Component component, NodeTypeEnum nodeType) { + TitanOperationStatus status; + Either>, TitanOperationStatus> eitherRequirements = getRequirements(component, nodeType, false); + if (eitherRequirements.isLeft()) { + status = TitanOperationStatus.OK; + Map> requirements = eitherRequirements.left().value(); + if (requirements != null && !requirements.isEmpty()) { + component.setRequirements(requirements); + } + } else { + status = eitherRequirements.right().value(); + } + return status; + } + + protected boolean isComponentExist(String componentId, NodeTypeEnum nodeType) { + boolean result = true; + Either compVertex = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (compVertex.isRight()) { + log.debug("failed to fetch vertex of component data for id {}", componentId); + result = false; + + } + return result; + } + + Either getLightComponent(String id, NodeTypeEnum nodeType, boolean inTransaction) { + Either metadataComponent = getMetadataComponent(id, nodeType, inTransaction); + if (metadataComponent.isRight()) { + + } + T component = null; + try { + log.debug("Starting to build light component of type {}, id {}", nodeType, id); + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + } + TitanGraph titanGraph = graphResult.left().value(); + Iterable vertecies = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), id).vertices(); + if (vertecies != null) { + Iterator iterator = vertecies.iterator(); + if (iterator != null && iterator.hasNext()) { + Vertex vertex = iterator.next(); + Map resourceProperties = titanGenericDao.getProperties(vertex); + ComponentMetadataData componentMetadataData = GraphElementFactory.createElement(nodeType.getName(), GraphElementTypeEnum.Node, resourceProperties, ComponentMetadataData.class); + component = (T) convertComponentMetadataDataToComponent(componentMetadataData); + + // get creator + Iterator iterCreator = vertex.edges(Direction.IN, GraphEdgeLabels.CREATOR.name()); + if (iterCreator.hasNext() == false) { + log.debug("no creator was defined for component {}", id); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Vertex vertexCreator = iterCreator.next().outVertex(); + UserData creator = GraphElementFactory.createElement(NodeTypeEnum.User.getName(), GraphElementTypeEnum.Node, titanGenericDao.getProperties(vertexCreator), UserData.class); + log.debug("Build component : set creator userId to {}", creator.getUserId()); + String fullName = buildFullName(creator); + log.debug("Build component : set creator full name to {}", fullName); + ((Component) component).setCreatorUserId(creator.getUserId()); + ((Component) component).setCreatorFullName(fullName); + + // get modifier + Iterator iterModifier = vertex.edges(Direction.IN, GraphEdgeLabels.LAST_MODIFIER.name()); + + if (iterModifier.hasNext() == false) { + log.debug("no modifier was defined for component {}", id); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Vertex vertexModifier = iterModifier.next().outVertex(); + UserData modifier = GraphElementFactory.createElement(NodeTypeEnum.User.getName(), GraphElementTypeEnum.Node, titanGenericDao.getProperties(vertexModifier), UserData.class); + log.debug("Build component : set last modifier userId to {}", creator.getUserId()); + fullName = buildFullName(modifier); + log.debug("Build component : set last modifier full name to {}", fullName); + ((Component) component).setLastUpdaterUserId(modifier.getUserId()); + ((Component) component).setLastUpdaterFullName(fullName); + + // get category + TitanOperationStatus status = setComponentCategoriesFromGraph((Component) component); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } else { + // Nothing found + log.debug("Component with id {} not found", id); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + } else { + // Nothing found + log.debug("Component with id {} not found", id); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + log.debug("Ended to build light component of type {}, id {}", nodeType, id); + return Either.left(component); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + Either getMetadataComponent(String id, NodeTypeEnum nodeType, boolean inTransaction) { + Component component = null; + try { + log.debug("Starting to build metadata component of type {}, id {}", nodeType, id); + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + } + TitanGraph titanGraph = graphResult.left().value(); + Iterable vertecies = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), id).vertices(); + if (vertecies != null) { + Iterator iterator = vertecies.iterator(); + if (iterator != null && iterator.hasNext()) { + Vertex vertex = iterator.next(); + Map resourceProperties = titanGenericDao.getProperties(vertex); + ComponentMetadataData componentMetadataData = GraphElementFactory.createElement(nodeType.getName(), GraphElementTypeEnum.Node, resourceProperties, ComponentMetadataData.class); + component = convertComponentMetadataDataToComponent(componentMetadataData); + } else { + // Nothing found + log.debug("Component with id {} not found", id); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + } else { + // Nothing found + log.debug("Component with id {} not found", id); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + log.debug("Ended to build metadata component of type {}, id {}", nodeType, id); + return Either.left(component); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + public Either getComponentInstanceCoutner(String origServiceId, NodeTypeEnum nodeType) { + Either result; + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + Either vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), origServiceId); + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of component metadata, nodeType:{} , id: {}", nodeType, origServiceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value())); + return result; + } + Vertex vertex = vertexService.left().value(); + Integer instanceCounter = vertex.value(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty()); + return Either.left(instanceCounter); + } + + protected TitanOperationStatus setComponentInstancesPropertiesFromGraph(String uniqueId, Component component) { + + List resourceInstances = component.getComponentInstances(); + + Map> resourceInstancesProperties = new HashMap<>(); + + Map> alreadyProcessedResources = new HashMap<>(); + + Map> alreadyProcessedInstances = new HashMap<>(); + + Map> processedInstances = new HashMap<>(); + + if (resourceInstances != null) { + + for (ComponentInstance resourceInstance : resourceInstances) { + + List path = new ArrayList<>(); + path.add(resourceInstance.getUniqueId()); + Either, TitanOperationStatus> componentInstanceProperties = componentInstanceOperation.getComponentInstanceProperties(resourceInstance, alreadyProcessedResources, alreadyProcessedInstances, + processedInstances, path); + + if (componentInstanceProperties.isRight()) { + TitanOperationStatus status = componentInstanceProperties.right().value(); + if (status != TitanOperationStatus.OK) { + return status; + } + } + + List listOfProps = componentInstanceProperties.left().value(); + String resourceInstanceUid = resourceInstance.getUniqueId(); + resourceInstancesProperties.put(resourceInstanceUid, listOfProps); + + // alreadyProcessedInstances.put(resourceInstance.getUniqueId(), + // resourceInstance); + + processedInstances.put(resourceInstance.getUniqueId(), new ImmutablePair(resourceInstance, path.size())); + path.remove(path.size() - 1); + + } + + } + + Either>, TitanOperationStatus> findAllPropertiesValuesOnInstances = componentInstanceOperation.findAllPropertyValueOnInstances(processedInstances); + // 1. check status + if (findAllPropertiesValuesOnInstances.isRight()) { + TitanOperationStatus status = findAllPropertiesValuesOnInstances.right().value(); + if (status != TitanOperationStatus.OK) { + return status; + } + } + // 2. merge data from rules on properties (resourceInstancesProperties) + propertyOperation.updatePropertiesByPropertyValues(resourceInstancesProperties, findAllPropertiesValuesOnInstances.left().value()); + + component.setComponentInstancesProperties(resourceInstancesProperties); + + return TitanOperationStatus.OK; + } + + protected TitanOperationStatus setComponentInstancesInputsFromGraph(String uniqueId, Component component) { + + Map> resourceInstancesInputs = new HashMap<>(); + TitanOperationStatus status = TitanOperationStatus.OK; + List componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + for (ComponentInstance resourceInstance : componentInstances) { + Either, TitanOperationStatus> eitherRIAttributes = inputOperation.getAllInputsOfResourceInstance(resourceInstance); + if (eitherRIAttributes.isRight()) { + if (eitherRIAttributes.right().value() != TitanOperationStatus.NOT_FOUND) { + status = eitherRIAttributes.right().value(); + break; + } + } else { + resourceInstancesInputs.put(resourceInstance.getUniqueId(), eitherRIAttributes.left().value()); + } + } + if (!resourceInstancesInputs.isEmpty()) + component.setComponentInstancesInputs(resourceInstancesInputs); + } + + return status; + } + + public Either getInvariantUUID(NodeTypeEnum nodeType, String componentId, boolean inTransaction) { + Either res = null; + try { + Either vertexByProperty = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (vertexByProperty.isRight()) { + TitanOperationStatus status = vertexByProperty.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + res = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + Vertex v = vertexByProperty.left().value(); + String invariantUUID = v.value(GraphPropertiesDictionary.INVARIANT_UUID.getProperty()); + + if (invariantUUID == null || invariantUUID.isEmpty()) { + + log.info("The component {} has empty invariant UUID.", componentId); + res = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.INVALID_ELEMENT)); + + } + res = Either.left(invariantUUID); + } + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + return res; + } + + protected TitanOperationStatus setGroupsFromGraph(String uniqueId, Component component, NodeTypeEnum nodeTypeEnum) { + + Either, TitanOperationStatus> res = groupOperation.getAllGroupsFromGraph(uniqueId, nodeTypeEnum); + if (res.isRight()) { + TitanOperationStatus status = res.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return TitanOperationStatus.OK; + } else { + return status; + } + } + component.setGroups(res.left().value()); + + return TitanOperationStatus.OK; + + } + + protected TitanOperationStatus setComponentInputsFromGraph(String uniqueId, Component component, boolean inTransaction) { + + List inputs = new ArrayList<>(); + TitanOperationStatus status = inputsOperation.findAllResourceInputs(uniqueId, inputs); + if (status == TitanOperationStatus.OK) { + component.setInputs(inputs); + } + + return status; + + } + + protected StorageOperationStatus deleteGroups(NodeTypeEnum nodeType, String componentId) { + + Either, StorageOperationStatus> deleteRes = groupOperation.deleteAllGroups(componentId, nodeType, true); + + if (deleteRes.isRight()) { + StorageOperationStatus status = deleteRes.right().value(); + return status; + } + + return StorageOperationStatus.OK; + + } + + protected StorageOperationStatus removeInputsFromComponent(NodeTypeEnum typeEnum, Component component) { + Either, StorageOperationStatus> deleteAllInputsAssociatedToNode = inputsOperation.deleteAllInputsAssociatedToNode(typeEnum, component.getUniqueId()); + return deleteAllInputsAssociatedToNode.isRight() ? deleteAllInputsAssociatedToNode.right().value() : StorageOperationStatus.OK; + } + + protected TitanOperationStatus associateInputsToComponent(NodeTypeEnum nodeType, ComponentMetadataData resourceData, List properties) { + + Either, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + return status; + } + + Map convertedProperties = new HashMap<>(); + + if (properties != null) { + for (InputDefinition propertyDefinition : properties) { + convertedProperties.put(propertyDefinition.getName(), propertyDefinition); + } + + Either, TitanOperationStatus> operationStatus = inputsOperation.addInputsToGraph(resourceData.getMetadataDataDefinition().getUniqueId(), nodeType, convertedProperties, allDataTypes.left().value()); + if (operationStatus.isLeft()) + return TitanOperationStatus.OK; + else + return operationStatus.right().value(); + } + + return TitanOperationStatus.OK; + + } + + protected TitanOperationStatus associateInputsToComponent(TitanVertex metadataVertex, String componentId, List properties) { + + Either, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + return status; + } + + Map convertedProperties = new HashMap<>(); + + if (properties != null) { + for (InputDefinition propertyDefinition : properties) { + convertedProperties.put(propertyDefinition.getName(), propertyDefinition); + } + + return inputsOperation.addInputsToGraph(metadataVertex, componentId, convertedProperties, allDataTypes.left().value()); + } + + return TitanOperationStatus.OK; + + } + + public Either, StorageOperationStatus> getAllComponentInstncesMetadata(String componentId, NodeTypeEnum nodeType) { + Instant start = Instant.now(); + Either, StorageOperationStatus> resourceInstancesOfService = componentInstanceOperation.getAllComponentInstancesMetadataOnly(componentId, nodeType); + Instant end = Instant.now(); + log.debug("TOTAL TIME BL GET INSTANCES: {}", Duration.between(start, end)); // prints + // PT1M3.553S + return resourceInstancesOfService; + } + + @Deprecated + public Either, ActionStatus> getComponentsFromCacheForCatalog(Set components, ComponentTypeEnum componentType) { + + Either, List, Set>, ActionStatus> componentsForCatalog = componentCache.getComponentsForCatalog(components, componentType); + if (componentsForCatalog.isLeft()) { + ImmutableTriple, List, Set> immutableTriple = componentsForCatalog.left().value(); + List foundComponents = immutableTriple.getLeft(); + + if (foundComponents != null) { + // foundComponents.forEach(p -> result.add((Resource)p)); + log.debug("The number of {}s added to catalog from cache is {}", componentType.name().toLowerCase(), foundComponents.size()); + + } + List foundDirtyComponents = immutableTriple.getMiddle(); + Set nonCachedComponents = immutableTriple.getRight(); + int numberDirtyResources = foundDirtyComponents == null ? 0 : foundDirtyComponents.size(); + int numberNonCached = nonCachedComponents == null ? 0 : nonCachedComponents.size(); + log.debug("The number of left {}s for catalog is {}", componentType.name().toLowerCase(), numberDirtyResources + numberNonCached); + return Either.left(foundComponents); + } + + return Either.right(componentsForCatalog.right().value()); + } + + public Either, TitanOperationStatus> getListOfHighestComponents(NodeTypeEnum nodeTypeEnum, Class clazz) { + + long startFetchAllStates = System.currentTimeMillis(); + Map propertiesToMatchHigest = new HashMap<>(); + propertiesToMatchHigest.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + Either, TitanOperationStatus> allHighestStates = titanGenericDao.getByCriteria(nodeTypeEnum, propertiesToMatchHigest, clazz); + if (allHighestStates.isRight() && allHighestStates.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right(allHighestStates.right().value()); + } + long endFetchAllStates = System.currentTimeMillis(); + + if (allHighestStates.isRight()) { + return Either.left(new ArrayList<>()); + } + List services = allHighestStates.left().value(); + + List certifiedHighest = new ArrayList<>(); + List notCertifiedHighest = new ArrayList<>(); + for (T reData : services) { + if (reData.getMetadataDataDefinition().getState().equals(LifecycleStateEnum.CERTIFIED.name())) { + certifiedHighest.add(reData); + } else { + notCertifiedHighest.add(reData); + } + } + + log.debug("Fetch catalog {}s all states: certified {}, noncertified {}", nodeTypeEnum.getName(), certifiedHighest.size(), notCertifiedHighest.size()); + log.debug("Fetch catalog {}s all states from graph took {} ms", nodeTypeEnum.getName(), endFetchAllStates - startFetchAllStates); + + HashMap serviceNames = new HashMap<>(); + for (T data : notCertifiedHighest) { + String serviceName = data.getMetadataDataDefinition().getName(); + serviceNames.put(serviceName, serviceName); + } + + for (T data : certifiedHighest) { + String serviceName = data.getMetadataDataDefinition().getName(); + if (!serviceNames.containsKey(serviceName)) { + notCertifiedHighest.add(data); + } + } + + return Either.left(notCertifiedHighest); + } + + protected Either getComponentFromCacheIfUpToDate(String uniqueId, ComponentMetadataData componentMetadataData, ComponentParametersView componentParametersView, Class clazz, + ComponentTypeEnum componentTypeEnum) { + + long start = System.currentTimeMillis(); + try { + + long lastModificationTime = componentMetadataData.getMetadataDataDefinition().getLastUpdateDate(); + Either cacheComponentRes = this.componentCache.getComponent(uniqueId, lastModificationTime); + if (cacheComponentRes.isLeft()) { + Component cachedComponent = cacheComponentRes.left().value(); + + // Must calculate allVersions + if (false == componentParametersView.isIgnoreAllVersions()) { + Class clazz1 = null; + switch (componentTypeEnum) { + case RESOURCE: + clazz1 = ResourceMetadataData.class; + break; + case SERVICE: + clazz1 = ServiceMetadataData.class; + break; + case PRODUCT: + clazz1 = ProductMetadataData.class; + break; + default: + break; + } + if (clazz1 != null) { + // long startGetAllVersions = + // System.currentTimeMillis(); + Either, TitanOperationStatus> versionList = getVersionList(componentTypeEnum.getNodeType(), cachedComponent.getVersion(), cachedComponent.getUUID(), cachedComponent.getSystemName(), clazz1); + // log.debug("Fetch all versions for component {} took + // {} ms", cachedComponent.getUniqueId(), + // System.currentTimeMillis() - startGetAllVersions); + if (versionList.isRight()) { + return Either.right(ActionStatus.GENERAL_ERROR); + } + + Map allVersions = versionList.left().value(); + cachedComponent.setAllVersions(allVersions); + } else { + return Either.right(ActionStatus.GENERAL_ERROR); + } + } + if (componentParametersView != null) { + cachedComponent = componentParametersView.filter(cachedComponent, componentTypeEnum); + } + return Either.left(clazz.cast(cachedComponent)); + } + + return Either.right(cacheComponentRes.right().value()); + + } finally { + log.trace("Fetch component {} with uid {} from cache took {} ms", componentTypeEnum.name().toLowerCase(), uniqueId, System.currentTimeMillis() - start); + } + } + + public Either, Set>, ActionStatus> getComponentsFromCacheForCatalog(Map components, ComponentTypeEnum componentType) { + + Either, Set>, ActionStatus> componentsForCatalog = componentCache.getComponentsForCatalog(components, componentType); + if (componentsForCatalog.isLeft()) { + ImmutablePair, Set> immutablePair = componentsForCatalog.left().value(); + List foundComponents = immutablePair.getLeft(); + + if (foundComponents != null) { + // foundComponents.forEach(p -> result.add((Resource)p)); + log.debug("The number of {}s added to catalog from cache is {}", componentType.name().toLowerCase(), foundComponents.size()); + } + Set leftComponents = immutablePair.getRight(); + int numberNonCached = leftComponents == null ? 0 : leftComponents.size(); + log.debug("The number of left {}s for catalog is {}", componentType.name().toLowerCase(), numberNonCached); + + ImmutablePair, Set> result = new ImmutablePair, Set>(foundComponents, leftComponents); + return Either.left(result); + } + + return Either.right(componentsForCatalog.right().value()); + } + + /** + * + * @param component + * @param inTransaction + * @param titanGenericDao + * @param clazz + * @return + */ + public Either updateComponentFilterResult(Component component, boolean inTransaction, TitanGenericDao titanGenericDao, Class clazz, NodeTypeEnum type, ComponentParametersView filterResult) { + Either result = null; + + try { + + log.debug("In updateComponent. received component uid = {}", (component == null ? null : component.getUniqueId())); + if (component == null) { + log.error("Service object is null"); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + ComponentMetadataData componentData = getMetaDataFromComponent(component); + + log.debug("After converting component to componentData. ComponentData = {}", componentData); + + if (componentData.getUniqueId() == null) { + log.error("Resource id is missing in the request."); + return Either.right(StorageOperationStatus.BAD_REQUEST); + } + + Either counterStatus = this.getComponentInstanceCoutner(component.getUniqueId(), component.getComponentType().getNodeType()); + + if (counterStatus.isRight()) { + + log.error("Cannot find componentInstanceCounter for component {} in the graph. Status is {}", componentData.getUniqueId(), counterStatus); + // result = sendError(status, + // StorageOperationStatus.USER_NOT_FOUND); + return result; + } + + componentData.setComponentInstanceCounter(counterStatus.left().value()); + + String modifierUserId = component.getLastUpdaterUserId(); + if (modifierUserId == null || modifierUserId.isEmpty()) { + log.error("userId is missing in the request."); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + Either findUser = findUser(modifierUserId); + + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user {} in the graph. Status is {}", modifierUserId, status); + // result = sendError(status, + // StorageOperationStatus.USER_NOT_FOUND); + return result; + } + + UserData modifierUserData = findUser.left().value(); + String resourceId = component.getUniqueId(); + + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreUsers(false); + componentParametersView.setIgnoreCategories(false); + componentParametersView.setIgnoreDerivedFrom(false); + componentParametersView.setIgnoreArtifacts(false); + Either currentComponentResult = this.getComponent(resourceId, componentParametersView, inTransaction); + if (currentComponentResult.isRight()) { + log.error("Cannot find resource with id {} in the graph.", resourceId); + result = Either.right(currentComponentResult.right().value()); + return result; + } + + Component currentComponent = (Component) currentComponentResult.left().value(); + String currentModifier = currentComponent.getLastUpdaterUserId(); + + if (currentModifier.equals(modifierUserData.getUniqueId())) { + log.debug("Graph LAST MODIFIER edge should not be changed since the modifier is the same as the last modifier."); + } else { + log.debug("Going to update the last modifier user of the resource from {} to {}", currentModifier, modifierUserId); + StorageOperationStatus status = moveLastModifierEdge(component, componentData, modifierUserData, type); + log.debug("Finish to update the last modifier user of the resource from {} to {}. Status is {}", currentModifier, modifierUserId, status); + if (status != StorageOperationStatus.OK) { + result = Either.right(status); + return result; + } + } + final long currentTimeMillis = System.currentTimeMillis(); + log.debug("Going to update the last Update Date of the resource from {} to {}", component.getLastUpdateDate(), currentTimeMillis); + component.setLastUpdateDate(currentTimeMillis); + + StorageOperationStatus checkCategories = validateCategories(currentComponent, component, componentData, type); + if (checkCategories != StorageOperationStatus.OK) { + result = Either.right(checkCategories); + return result; + } + + List tags = component.getTags(); + if (tags != null && false == tags.isEmpty()) { + Either, StorageOperationStatus> tagsResult = createNewTagsList(tags); + if (tagsResult.isRight()) { + result = Either.right(tagsResult.right().value()); + return result; + } + List tagsToCreate = tagsResult.left().value(); + if (tagsToCreate != null && !tagsToCreate.isEmpty()) { + tagsToCreate = ImmutableSet.copyOf(tagsToCreate).asList(); + for (TagData tagData : tagsToCreate) { + log.debug("Before creating tag {}", tagData); + Either createTagResult = titanGenericDao.createNode(tagData, TagData.class); + if (createTagResult.isRight()) { + TitanOperationStatus status = createTagResult.right().value(); + log.error("Cannot find tag {} in the graph. Status is {}", tagData, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + log.debug("After creating tag {}", tagData); + } + } + } + + Either updateNode = titanGenericDao.updateNode(componentData, ComponentMetadataData.class); + + if (updateNode.isRight()) { + log.error("Failed to update resource {}. Status is {}", component.getUniqueId(), updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + + ComponentMetadataData updatedResourceData = updateNode.left().value(); + log.debug("ComponentData After update is {}", updatedResourceData); + + // DE230195 in case resource name changed update TOSCA artifacts + // file names accordingly + String newSystemName = updatedResourceData.getMetadataDataDefinition().getSystemName(); + if (newSystemName != null && !newSystemName.equals(currentComponent.getSystemName())) { + Map toscaArtifacts = component.getToscaArtifacts(); + if (toscaArtifacts != null) { + for (Entry artifact : toscaArtifacts.entrySet()) { + Either updateName = generateAndUpdateToscaFileName(component.getComponentType().getValue().toLowerCase(), newSystemName, updatedResourceData.getMetadataDataDefinition().getUniqueId(), + type, artifact.getValue()); + if (updateName.isRight()) { + result = Either.right(updateName.right().value()); + return result; + } + } + } + + } + + if (component.getComponentType().equals(ComponentTypeEnum.RESOURCE)) { + updateDerived(component, currentComponent, componentData, component.getClass()); + } + + Either updatedResource = getComponent(component.getUniqueId(), filterResult, inTransaction); + if (updatedResource.isRight()) { + log.error("Resource id is missing in the request. status is {}", updatedResource.right().value()); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + T updatedResourceValue = updatedResource.left().value(); + result = Either.left(updatedResourceValue); + + if (log.isDebugEnabled()) { + // String json = prettyJson.toJson(result.left().value()); + // log.debug("Resource retrieved after update is {}", json); + } + + return result; + + } finally { + + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("updateComponent operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("updateComponent operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java new file mode 100644 index 0000000000..aafa4ba444 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.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.model.operations.impl; + +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.model.operations.api.IConsumerOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ConsumerData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("consumer-operation") +public class ConsumerOperation implements IConsumerOperation { + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + private static Logger log = LoggerFactory.getLogger(ConsumerOperation.class.getName()); + + public ConsumerOperation() { + } + + @Override + public Either getCredentials(String consumerName) { + Either result = null; + log.debug("retriving Credentials for: {}.", consumerName); + Either getNode = titanGenericDao.getNode(GraphPropertiesDictionary.CONSUMER_NAME.getProperty(), consumerName, ConsumerData.class); + if (getNode.isRight()) { + TitanOperationStatus status = getNode.right().value(); + log.error("Error returned after get Consumer Data node " + consumerName + ". status returned is " + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + ConsumerData consumerData = getNode.left().value(); + return Either.left(consumerData); + } + + @Override + public Either createCredentials(ConsumerData consumerData) { + return createCredentials(consumerData, false); + } + + @Override + public Either createCredentials(ConsumerData consumerData, boolean inTransaction) { + Either result = null; + try { + log.debug("creating Credentials for: {}.", consumerData.getUniqueId()); + Either createNode = titanGenericDao.createNode(consumerData, ConsumerData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Error returned after creating Consumer Data node " + consumerData.getUniqueId() + ". status returned is " + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + ConsumerData createdConsumerData = createNode.left().value(); + result = Either.left(createdConsumerData); + return result; + } finally { + handleTransaction(inTransaction, result); + } + } + + @Override + public Either deleteCredentials(String consumerName) { + return deleteCredentials(consumerName, false); + } + + @Override + public Either deleteCredentials(String consumerName, boolean inTransaction) { + Either result = null; + try { + log.debug("delete Credentials for: {}", consumerName); + Either deleteNode = titanGenericDao.deleteNode(GraphPropertiesDictionary.CONSUMER_NAME.getProperty(), consumerName, ConsumerData.class); + if (deleteNode.isRight()) { + TitanOperationStatus status = deleteNode.right().value(); + log.error("Error returned after delete Consumer Data node {}. Status returned is {}", consumerName, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ConsumerData deletedConsumerData = deleteNode.left().value(); + result = Either.left(deletedConsumerData); + return result; + } finally { + handleTransaction(inTransaction, result); + } + + } + + @Override + public Either updateCredentials(ConsumerData consumerData) { + return updateCredentials(consumerData, false); + } + + @Override + public Either updateCredentials(ConsumerData consumerData, boolean inTransaction) { + + Either result = null; + try { + log.debug("update Credentials for: {}.", consumerData.getUniqueId()); + Either updateNode = titanGenericDao.updateNode(consumerData, ConsumerData.class); + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + log.error("Error returned after delete Consumer Data node {}. Status returned is {}", consumerData.getUniqueId(), status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + ConsumerData updatedConsumerData = updateNode.left().value(); + result = Either.left(updatedConsumerData); + return result; + } finally { + handleTransaction(inTransaction, result); + } + } + + private void handleTransaction(boolean inTransaction, Either result) { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java new file mode 100644 index 0000000000..1420ce08d8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java @@ -0,0 +1,115 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.common.util.ZipUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("csar-operation") +public class CsarOperation { + + private static Logger log = LoggerFactory.getLogger(CsarOperation.class.getName()); + + @javax.annotation.Resource + private OnboardingClient onboardingClient; + + public static void main(String[] args) { + + CsarOperation csarOperation = new CsarOperation(); + csarOperation.init(); + + String csarUuid = "70025CF6081B489CA7B1CBA583D5278D"; + Either, StorageOperationStatus> csar = csarOperation.getCsar(csarUuid, null); + System.out.println(csar.left().value()); + + } + + @PostConstruct + public void init() { + + } + + // Mock returning a file from the file system until we have API from onboarding + public Either, StorageOperationStatus> getMockCsar(String csarUuid) { + File dir = new File("/var/tmp/mockCsar"); + FileFilter fileFilter = new WildcardFileFilter("*.csar"); + File[] files = dir.listFiles(fileFilter); + for (int i = 0; i < files.length; i++) { + File csar = files[i]; + if (csar.getName().startsWith(csarUuid)) { + log.debug("Found CSAR file {} matching the passed csarUuid {}", csar.getAbsolutePath(), csarUuid); + byte[] data; + try { + data = Files.readAllBytes(csar.toPath()); + } catch (IOException e) { + log.debug("Error reading mock file for CSAR, error: {}", e); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Map readZip = ZipUtil.readZip(data); + return Either.left(readZip); + } + } + log.debug("Couldn't find mock file for CSAR starting with {}", csarUuid); + return Either.right(StorageOperationStatus.CSAR_NOT_FOUND); + } + + /** + * get csar from remote repository + * + * @param csarUuid + * @return + */ + public Either, StorageOperationStatus> getCsar(String csarUuid, User user) { + + Either, StorageOperationStatus> result = onboardingClient.getCsar(csarUuid, + user.getUserId()); + + if (result.isRight()) { + log.debug("Cannot find csar {}. Status returned is {}", csarUuid, result.right().value()); + } else { + Map values = result.left().value(); + if (values != null) { + log.debug("The returned files are {}", values.keySet()); + } + } + + return result; + } + + public OnboardingClient getOnboardingClient() { + return onboardingClient; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java new file mode 100644 index 0000000000..b887c5b212 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.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.model.operations.impl; + +import org.openecomp.sdc.be.dao.api.ResourceUploadStatus; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; + +public class DaoStatusConverter { + + public static StorageOperationStatus convertTitanStatusToStorageStatus(TitanOperationStatus titanStatus) { + + if (titanStatus == null) { + return StorageOperationStatus.GENERAL_ERROR; + } + + switch (titanStatus) { + + case OK: + return StorageOperationStatus.OK; + + case NOT_CONNECTED: + return StorageOperationStatus.CONNECTION_FAILURE; + + case NOT_FOUND: + return StorageOperationStatus.NOT_FOUND; + + case NOT_CREATED: + return StorageOperationStatus.SCHEMA_ERROR; + + case INDEX_CANNOT_BE_CHANGED: + return StorageOperationStatus.SCHEMA_ERROR; + + case MISSING_UNIQUE_ID: + return StorageOperationStatus.BAD_REQUEST; + case ALREADY_LOCKED: + return StorageOperationStatus.FAILED_TO_LOCK_ELEMENT; + + case TITAN_SCHEMA_VIOLATION: + return StorageOperationStatus.SCHEMA_VIOLATION; + + case INVALID_ID: + return StorageOperationStatus.INVALID_ID; + case MATCH_NOT_FOUND: + return StorageOperationStatus.MATCH_NOT_FOUND; + + case ILLEGAL_ARGUMENT: + return StorageOperationStatus.BAD_REQUEST; + // case HTTP_PROTOCOL_ERROR: + // return StorageOperationStatus.HTTP_PROTOCOL_ERROR; + // case DB_NOT_AVAILABLE: + // return StorageOperationStatus.STORAGE_NOT_AVAILABLE; + // case DB_READ_ONLY: + // return StorageOperationStatus.READ_ONLY_STORAGE; + // case BAD_REQUEST: + // return StorageOperationStatus.BAD_REQUEST; + // case LEGACY_INDEX_ERROR: + // return StorageOperationStatus.STORAGE_LEGACY_INDEX_ERROR; + // case SCHEMA_ERROR: + // return StorageOperationStatus.SCHEMA_ERROR; + // case TRANSACTION_ERROR: + // return StorageOperationStatus.TRANSACTION_ERROR; + // case EXECUTION_FAILED: + // return StorageOperationStatus.EXEUCTION_FAILED; + case ALREADY_EXIST: + return StorageOperationStatus.ENTITY_ALREADY_EXISTS; + case PROPERTY_NAME_ALREADY_EXISTS: + return StorageOperationStatus.PROPERTY_NAME_ALREADY_EXISTS; + case INVALID_PROPERTY: + return StorageOperationStatus.INVALID_PROPERTY; + // case WRONG_INPUT: + // return StorageOperationStatus.BAD_REQUEST; + // case GENERAL_ERROR: + // return StorageOperationStatus.GENERAL_ERROR; + // case NOT_SUPPORTED: + // return StorageOperationStatus.OPERATION_NOT_SUPPORTED; + + default: + return StorageOperationStatus.GENERAL_ERROR; + } + + } + + public static StorageOperationStatus convertRsrcUploadStatusToStorageStatus( + ResourceUploadStatus resourceUploadStatus) { + if (resourceUploadStatus == null) { + return StorageOperationStatus.GENERAL_ERROR; + } + switch (resourceUploadStatus) { + case OK: + return StorageOperationStatus.OK; + case ALREADY_EXIST: + return StorageOperationStatus.ENTITY_ALREADY_EXISTS; + case NOT_EXIST: + return StorageOperationStatus.ARTIFACT_NOT_FOUND; + case SERVICE_NOT_EXIST: + case COMPONENT_NOT_EXIST: + return StorageOperationStatus.NOT_FOUND; + default: + return StorageOperationStatus.GENERAL_ERROR; + } + } + + public static StorageOperationStatus convertCassandraStatusToStorageStatus(CassandraOperationStatus status) { + if (status == null) { + return StorageOperationStatus.GENERAL_ERROR; + } + switch (status) { + case OK: + return StorageOperationStatus.OK; + case CLUSTER_NOT_CONNECTED: + return StorageOperationStatus.CONNECTION_FAILURE; + case KEYSPACE_NOT_CONNECTED: + return StorageOperationStatus.STORAGE_NOT_AVAILABLE; + case NOT_FOUND: + return StorageOperationStatus.NOT_FOUND; + + default: + return StorageOperationStatus.GENERAL_ERROR; + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java new file mode 100644 index 0000000000..248a1d0460 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java @@ -0,0 +1,902 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Vertex; +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.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +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.category.CategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; +import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.PropertyScope; +import org.openecomp.sdc.be.model.Tag; +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.resources.data.TagData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.GroupingData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanGraph; +//import com.tinkerpop.blueprints.Vertex; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@Component("element-operation") +public class ElementOperation implements IElementOperation { + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + public ElementOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(ElementOperation.class.getName()); + + /* + * Old flow + */ + @Override + public Either, ActionStatus> getAllServiceCategories() { + return getAllCategories(NodeTypeEnum.ServiceNewCategory, false); + } + + @Override + public Either, ActionStatus> getAllResourceCategories() { + return getAllCategories(NodeTypeEnum.ResourceNewCategory, false); + } + + @Override + public Either, ActionStatus> getAllProductCategories() { + return getAllCategories(NodeTypeEnum.ProductCategory, false); + } + /* + * + */ + + /* + * New flow + */ + @Override + public Either createCategory(CategoryDefinition category, NodeTypeEnum nodeType) { + return createCategory(category, nodeType, false); + } + + @Override + public Either createCategory(CategoryDefinition category, NodeTypeEnum nodeType, + boolean inTransaction) { + Either result = null; + category.setUniqueId(UniqueIdBuilder.buildCategoryUid(category.getNormalizedName(), nodeType)); + CategoryData categoryData = new CategoryData(nodeType, category); + + try { + Either createNode = titanGenericDao.createNode(categoryData, + CategoryData.class); + if (createNode.isRight()) { + TitanOperationStatus value = createNode.right().value(); + ActionStatus actionStatus = ActionStatus.GENERAL_ERROR; + log.debug("Problem while creating category, reason {}", value); + if (value == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) { + actionStatus = ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS; + } + result = Either.right(actionStatus); + return result; + } + CategoryDefinition created = new CategoryDefinition(createNode.left().value().getCategoryDataDefinition()); + result = Either.left(created); + return result; + } finally { + if (inTransaction == false) { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + } + + @Override + public Either createSubCategory(String categoryId, + SubCategoryDefinition subCategory, NodeTypeEnum nodeType) { + return createSubCategory(categoryId, subCategory, nodeType, false); + } + + @Override + public Either createSubCategory(String categoryId, + SubCategoryDefinition subCategory, NodeTypeEnum nodeType, boolean inTransaction) { + + Either result = null; + + try { + // create edge from category to sub-category + Either categoryNode = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class); + ActionStatus actionStatus = ActionStatus.GENERAL_ERROR; + if (categoryNode.isRight()) { + TitanOperationStatus titanOperationStatus = categoryNode.right().value(); + log.debug("Problem while fetching category, reason {}", titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND; + } + result = Either.right(actionStatus); + return result; + } + + CategoryDataDefinition categoryDataDefinition = categoryNode.left().value().getCategoryDataDefinition(); + subCategory.setUniqueId(UniqueIdBuilder.buildSubCategoryUid(categoryDataDefinition.getUniqueId(), + subCategory.getNormalizedName())); + SubCategoryData subCategoryData = new SubCategoryData(nodeType, subCategory); + + Either subCategoryNode = titanGenericDao.createNode(subCategoryData, + SubCategoryData.class); + if (subCategoryNode.isRight()) { + TitanOperationStatus titanOperationStatus = subCategoryNode.right().value(); + log.debug("Problem while creating category, reason {}", titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) { + actionStatus = ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY; + } + result = Either.right(actionStatus); + return result; + } + + Either relation = titanGenericDao.createRelation( + categoryNode.left().value(), subCategoryNode.left().value(), GraphEdgeLabels.SUB_CATEGORY, null); + if (relation.isRight()) { + log.debug("Problem while create relation between category and sub-category ", relation.right().value()); + result = Either.right(actionStatus); + return result; + } + SubCategoryDefinition subCategoryCreated = new SubCategoryDefinition( + subCategoryNode.left().value().getSubCategoryDataDefinition()); + result = Either.left(subCategoryCreated); + return result; + } finally { + if (inTransaction == false) { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + } + + @Override + public Either createGrouping(String subCategoryId, GroupingDefinition grouping, + NodeTypeEnum nodeType) { + + Either result = null; + + try { + // create edge from sub-category to grouping + Either subCategoryNode = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class); + ActionStatus actionStatus = ActionStatus.GENERAL_ERROR; + if (subCategoryNode.isRight()) { + TitanOperationStatus titanOperationStatus = subCategoryNode.right().value(); + log.debug("Problem while fetching category, reason {}", titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) { + actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND; + } + result = Either.right(actionStatus); + return result; + } + + SubCategoryDataDefinition subCatData = subCategoryNode.left().value().getSubCategoryDataDefinition(); + grouping.setUniqueId( + UniqueIdBuilder.buildGroupingUid(subCatData.getUniqueId(), grouping.getNormalizedName())); + GroupingData groupingData = new GroupingData(nodeType, grouping); + + Either groupingNode = titanGenericDao.createNode(groupingData, + GroupingData.class); + if (groupingNode.isRight()) { + TitanOperationStatus titanOperationStatus = groupingNode.right().value(); + log.debug("Problem while creating grouping, reason {}", titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + actionStatus = ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY; + } + result = Either.right(actionStatus); + return result; + } + + Either relation = titanGenericDao.createRelation( + subCategoryNode.left().value(), groupingNode.left().value(), GraphEdgeLabels.GROUPING, null); + if (relation.isRight()) { + log.debug("Problem while create relation between sub-category and grouping", relation.right().value()); + result = Either.right(actionStatus); + return result; + } + GroupingDefinition groupingCreated = new GroupingDefinition( + groupingNode.left().value().getGroupingDataDefinition()); + result = Either.left(groupingCreated); + return result; + } finally { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + + @Override + public Either, ActionStatus> getAllCategories(NodeTypeEnum nodeType, + boolean inTransaction) { + try { + if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory + && nodeType != NodeTypeEnum.ProductCategory) { + log.debug("Unknown category type {}", nodeType.name()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + + Either, TitanOperationStatus> either = titanGenericDao + .getAll(nodeType, org.openecomp.sdc.be.resources.data.category.CategoryData.class); + if (either.isRight() && (either.right().value() != TitanOperationStatus.NOT_FOUND)) { + log.debug("Problem while get all categories. reason - {}", either.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List categoryDataList = either.isLeft() ? either.left().value() : null; + List categoryList = new ArrayList(); + if (categoryDataList != null) { + for (CategoryData elem : categoryDataList) { + CategoryDataDefinition categoryDataDefinition = elem.getCategoryDataDefinition(); + + CategoryDefinition categoryDefinition = new CategoryDefinition(categoryDataDefinition); + String categoryName = categoryDataDefinition.getName(); + log.trace("Found category {}, category type {}", categoryName, nodeType); + TitanOperationStatus setSubCategories = setSubCategories(nodeType, categoryDefinition); + if (setSubCategories != TitanOperationStatus.OK) { + log.debug("Failed to set sub-categories for category {}, category type {}, error {}", + categoryName, nodeType, setSubCategories); + return Either.right(ActionStatus.GENERAL_ERROR); + } + categoryList.add(categoryDefinition); + } + } + return Either.left(categoryList); + } finally { + if (!inTransaction) { + titanGenericDao.commit(); + } + } + } + + private TitanOperationStatus setSubCategories(NodeTypeEnum parentNodeType, CategoryDefinition parentCategory) { + NodeTypeEnum childNodeType = getChildNodeType(parentNodeType); + if (childNodeType != null) { + String categoryName = parentCategory.getName(); + log.trace("Getting sub-categories for category {}, category type {}", categoryName, parentNodeType); + Either>, TitanOperationStatus> parentNode = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentCategory.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, childNodeType, SubCategoryData.class); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + log.trace("Didn't find subcategories for category {}, category type {}", categoryName, + parentNodeType); + titanOperationStatus = TitanOperationStatus.OK; + } + return titanOperationStatus; + } + List> subsCategoriesData = parentNode.left().value(); + List subCategoriesDefinitions = new ArrayList<>(); + for (ImmutablePair subCatPair : subsCategoriesData) { + SubCategoryDataDefinition subCategoryDataDefinition = subCatPair.getLeft() + .getSubCategoryDataDefinition(); + SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition(subCategoryDataDefinition); + + log.trace("Found sub-category {} for category {}, category type {}", + subCategoryDataDefinition.getName(), categoryName, parentNodeType); + TitanOperationStatus setGroupings = setGroupings(childNodeType, subCategoryDefinition); + if (setGroupings != TitanOperationStatus.OK) { + log.debug("Failed to set groupings for sub-category {}, sub-category type {}, error {}", + subCategoryDataDefinition.getName(), childNodeType, setGroupings); + return TitanOperationStatus.GENERAL_ERROR; + } + subCategoriesDefinitions.add(subCategoryDefinition); + } + parentCategory.setSubcategories(subCategoriesDefinitions); + } + return TitanOperationStatus.OK; + } + + private TitanOperationStatus setGroupings(NodeTypeEnum parentNodeType, SubCategoryDefinition parentSubCategory) { + NodeTypeEnum childNodeType = getChildNodeType(parentNodeType); + if (childNodeType != null) { + String subCategoryName = parentSubCategory.getName(); + log.trace("Getting groupings for subcategory {}, subcategory type {}", subCategoryName, parentNodeType); + Either>, TitanOperationStatus> parentNode = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentSubCategory.getUniqueId(), + GraphEdgeLabels.GROUPING, childNodeType, GroupingData.class); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + log.trace("Didn't find groupings for subcategory {}, subcategory type {}", subCategoryName, + parentNodeType); + titanOperationStatus = TitanOperationStatus.OK; + } + return titanOperationStatus; + } + List> groupingData = parentNode.left().value(); + List groupingDefinitions = new ArrayList<>(); + for (ImmutablePair groupPair : groupingData) { + GroupingDataDefinition groupingDataDefinition = groupPair.getLeft().getGroupingDataDefinition(); + log.trace("Found grouping {} for sub-category {}, sub-category type {}", + groupingDataDefinition.getName(), subCategoryName, parentNodeType); + groupingDefinitions.add(new GroupingDefinition(groupingDataDefinition)); + } + parentSubCategory.setGroupings(groupingDefinitions); + } + return TitanOperationStatus.OK; + } + + private static NodeTypeEnum getChildNodeType(NodeTypeEnum parentTypeEnum) { + NodeTypeEnum res = null; + switch (parentTypeEnum) { + case ResourceNewCategory: + res = NodeTypeEnum.ResourceSubcategory; + break; + case ProductCategory: + res = NodeTypeEnum.ProductSubcategory; + break; + case ProductSubcategory: + res = NodeTypeEnum.ProductGrouping; + break; + default: + break; + } + return res; + } + + @Override + public Either getCategory(NodeTypeEnum nodeType, String categoryId) { + try { + if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory + && nodeType != NodeTypeEnum.ProductCategory) { + log.debug("Unknown category type {}", nodeType.name()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + + Either categoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class); + if (categoryDataEither.isRight()) { + TitanOperationStatus titanOperationStatus = categoryDataEither.right().value(); + log.debug("Problem while get category by id {}. reason {}", categoryId, titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND); + } + return Either.right(ActionStatus.GENERAL_ERROR); + } + CategoryDataDefinition categoryDataDefinition = categoryDataEither.left().value() + .getCategoryDataDefinition(); + return Either.left(new CategoryDefinition(categoryDataDefinition)); + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either getSubCategory(NodeTypeEnum nodeType, String subCategoryId) { + try { + if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) { + log.debug("Unknown sub-category type {}", nodeType.name()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + + Either subCategoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class); + if (subCategoryDataEither.isRight()) { + TitanOperationStatus titanOperationStatus = subCategoryDataEither.right().value(); + log.debug("Problem while get sub-category by id {}. reason {}", subCategoryId, titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND); + } + return Either.right(ActionStatus.GENERAL_ERROR); + } + SubCategoryDataDefinition subCategoryDataDefinition = subCategoryDataEither.left().value() + .getSubCategoryDataDefinition(); + return Either.left(new SubCategoryDefinition(subCategoryDataDefinition)); + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either deleteCategory(NodeTypeEnum nodeType, String categoryId) { + Either result = null; + try { + if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory + && nodeType != NodeTypeEnum.ProductCategory) { + log.debug("Unknown category type {}", nodeType.name()); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Either categoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class); + if (categoryDataEither.isRight()) { + log.debug("Failed to retrieve category for id {} ", categoryId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Couldn't fetch titan graph"); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + TitanGraph tGraph = graph.left().value(); + + Iterable verticesArtifact = tGraph.query() + .has(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId).vertices(); + Iterator iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No category node for id = {}", categoryId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Vertex artifactV = iterator.next(); + artifactV.remove(); + CategoryDefinition deleted = new CategoryDefinition( + categoryDataEither.left().value().getCategoryDataDefinition()); + result = Either.left(deleted); + return result; + } finally { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + + @Override + public Either deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId) { + Either result = null; + try { + if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) { + log.debug("Unknown sub-category type {}", nodeType.name()); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Either subCategoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class); + if (subCategoryDataEither.isRight()) { + log.debug("Failed to retrieve sub-category for id {}", subCategoryId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Couldn't fetch titan graph"); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + TitanGraph tGraph = graph.left().value(); + + Iterable verticesArtifact = tGraph.query() + .has(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId).vertices(); + Iterator iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No sub-category node for id {}", subCategoryId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Vertex artifactV = iterator.next(); + artifactV.remove(); + ; + SubCategoryDefinition deleted = new SubCategoryDefinition( + subCategoryDataEither.left().value().getSubCategoryDataDefinition()); + result = Either.left(deleted); + return result; + } finally { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + + } + + @Override + public Either deleteGrouping(NodeTypeEnum nodeType, String groupingId) { + Either result = null; + try { + if (nodeType != NodeTypeEnum.ProductGrouping) { + log.debug("Unknown grouping type {}", nodeType.name()); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Either groupingDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class); + if (groupingDataEither.isRight()) { + log.debug("Failed to retrieve grouping for id {}", groupingId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Couldn't fetch titan graph"); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + TitanGraph tGraph = graph.left().value(); + + Iterable verticesArtifact = tGraph.query() + .has(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId).vertices(); + Iterator iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No grouping node for id {}", groupingId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Vertex artifactV = iterator.next(); + artifactV.remove(); + ; + GroupingDefinition deleted = new GroupingDefinition( + groupingDataEither.left().value().getGroupingDataDefinition()); + result = Either.left(deleted); + return result; + } finally { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + + @Override + public Either isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName) { + + Map properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + try { + Either, TitanOperationStatus> categoryEither = titanGenericDao.getByCriteria(nodeType, + properties, CategoryData.class); + if (categoryEither.isRight() && categoryEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get categories, nodeType {}, normalizedName {}, error {}", nodeType, + normalizedName, categoryEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List categoryList = (categoryEither.isLeft() ? categoryEither.left().value() : null); + if (categoryList != null && categoryList.size() > 0) { + log.debug("Found category for nodeType {} with normalizedName {}", nodeType, normalizedName); + if (categoryList.size() > 1) { + log.debug("Found more than 1 unique categories for nodeType {} with normalizedName", nodeType, + normalizedName); + return Either.right(ActionStatus.GENERAL_ERROR); + } + return Either.left(false); + } else { + log.debug("Category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, + normalizedName); + return Either.left(true); + } + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, + String subCategoryNormName, String parentCategoryId) { + + String subCategoryId = UniqueIdBuilder.buildSubCategoryUid(parentCategoryId, subCategoryNormName); + try { + Either subCategoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class); + if (subCategoryDataEither.isRight() + && subCategoryDataEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get sub-category with id {}, error {}", subCategoryId, + subCategoryDataEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + SubCategoryData subCategoryData = (subCategoryDataEither.isLeft() ? subCategoryDataEither.left().value() + : null); + if (subCategoryData != null) { + log.debug("Found sub-category with id {}", subCategoryId); + return Either.left(false); + } else { + log.debug("Sub-category for id {} doesn't exist in graph", subCategoryId); + return Either.left(true); + } + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, + String parentSubCategoryId) { + + String groupingId = UniqueIdBuilder.buildGroupingUid(parentSubCategoryId, groupingNormName); + try { + Either groupingDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class); + if (groupingDataEither.isRight() && groupingDataEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get grouping with id {}, error {}", groupingId, + groupingDataEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + GroupingData groupingData = (groupingDataEither.isLeft() ? groupingDataEither.left().value() : null); + if (groupingData != null) { + log.debug("Found grouping with id {}", groupingId); + return Either.left(false); + } else { + log.debug("Grouping for id {} doesn't exist in graph", groupingId); + return Either.left(true); + } + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either getSubCategoryUniqueForType(NodeTypeEnum nodeType, + String normalizedName) { + Map properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + try { + Either, TitanOperationStatus> subCategoryEither = titanGenericDao + .getByCriteria(nodeType, properties, SubCategoryData.class); + if (subCategoryEither.isRight() && subCategoryEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get sub-categories, nodeType {}, normalizedName {}, error {}", nodeType, + normalizedName, subCategoryEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List subCategoryList = (subCategoryEither.isLeft() ? subCategoryEither.left().value() + : null); + if (subCategoryList != null && subCategoryList.size() > 0) { + log.debug("Found sub-category for nodeType {} with normalizedName {}", nodeType, normalizedName); + SubCategoryData subCategoryData = subCategoryList.get(0); + SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition( + subCategoryData.getSubCategoryDataDefinition()); + return Either.left(subCategoryDefinition); + } else { + log.debug("Sub-category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, + normalizedName); + return Either.left(null); + } + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either getGroupingUniqueForType(NodeTypeEnum nodeType, + String groupingNormalizedName) { + Map properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), groupingNormalizedName); + try { + Either, TitanOperationStatus> groupingEither = titanGenericDao.getByCriteria(nodeType, + properties, GroupingData.class); + if (groupingEither.isRight() && groupingEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get grouping, nodeType {}, normalizedName {}, error {}", nodeType, + groupingNormalizedName, groupingEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List groupingList = (groupingEither.isLeft() ? groupingEither.left().value() : null); + if (groupingList != null && groupingList.size() > 0) { + log.debug("Found grouping for nodeType {} with normalizedName {}", nodeType, groupingNormalizedName); + GroupingData groupingData = groupingList.get(0); + GroupingDefinition groupingDefinition = new GroupingDefinition( + groupingData.getGroupingDataDefinition()); + return Either.left(groupingDefinition); + } else { + log.debug("Grouping for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, + groupingNormalizedName); + return Either.left(null); + } + } finally { + titanGenericDao.commit(); + } + } + + /* + * + */ + + @Override + public Either, ActionStatus> getAllTags() { + try { + Either, TitanOperationStatus> either = titanGenericDao.getAll(NodeTypeEnum.Tag, + TagData.class); + if (either.isRight()) { + log.debug("Problem while get all tags. reason - {}", either.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List tagDataList = either.left().value(); + List tagList = convertToListOfTag(tagDataList); + return Either.left(tagList); + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either getCategoryData( + String name, NodeTypeEnum type, Class clazz) { + if (name != null) { + String categoryUid = null; + if (type == NodeTypeEnum.ResourceCategory) { + String[] categoryFields = name.split("/"); + if (categoryFields.length != 2) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + categoryUid = UniqueIdBuilder.buildResourceCategoryUid(categoryFields[0], categoryFields[1], type); + } else { + categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type); + } + Either either = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(type), + categoryUid, clazz); + + if (either.isRight()) { + TitanOperationStatus titanOperationStatus = either.right().value(); + log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name()); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } else { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + return Either.left((org.openecomp.sdc.be.resources.data.CategoryData) either.left().value()); + } else { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + + private List convertToListOfTag(List tagDataList) { + List tagList = new ArrayList(); + for (TagData elem : tagDataList) { + Tag tag = new Tag(); + tag.setName(elem.getName()); + tagList.add(tag); + } + return tagList; + } + + @Override + public Either, ActionStatus> getAllPropertyScopes() { + // Mock + List propertyScopes = new ArrayList(); + PropertyScope propertyScope1 = new PropertyScope(); + propertyScope1.setName("A&AI"); + PropertyScope propertyScope2 = new PropertyScope(); + propertyScope2.setName("Order"); + PropertyScope propertyScope3 = new PropertyScope(); + propertyScope3.setName("Runtime"); + propertyScopes.add(propertyScope1); + propertyScopes.add(propertyScope2); + propertyScopes.add(propertyScope3); + return Either.left(propertyScopes); + } + + @Override + public Either, ActionStatus> getAllArtifactTypes() { + List artifactTypes = new ArrayList(); + + List artifactTypesList = ConfigurationManager.getConfigurationManager().getConfiguration() + .getArtifactTypes(); + for (String artifactType : artifactTypesList) { + ArtifactType artifactT = new ArtifactType(); + artifactT.setName(artifactType); + artifactTypes.add(artifactT); + } + return Either.left(artifactTypes); + } + + @Override + public Either, ActionStatus> getAllDeploymentArtifactTypes() { + + Map artifactTypes = new HashMap(); + Map artifactResourceTypes = ConfigurationManager.getConfigurationManager() + .getConfiguration().getResourceDeploymentArtifacts(); + Map artifactServiceTypes = ConfigurationManager.getConfigurationManager() + .getConfiguration().getServiceDeploymentArtifacts(); + Map artifactResourceInstanceTypes = ConfigurationManager + .getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts(); + + artifactTypes.put("resourceDeploymentArtifacts", artifactResourceTypes); + artifactTypes.put("serviceDeploymentArtifacts", artifactServiceTypes); + artifactTypes.put("resourceInstanceDeploymentArtifacts", artifactResourceInstanceTypes); + + return Either.left(artifactTypes); + + } + + @Override + public Either getDefaultHeatTimeout() { + return Either.left(ConfigurationManager.getConfigurationManager().getConfiguration() + .getDefaultHeatArtifactTimeoutMinutes()); + } + + @Override + public Either, ActionStatus> getResourceTypesMap() { + ResourceTypeEnum[] enumConstants = ResourceTypeEnum.class.getEnumConstants(); + Map resourceTypes = new HashMap(); + if (enumConstants != null) { + for (int i = 0; i < enumConstants.length; ++i) { + resourceTypes.put(enumConstants[i].name(), enumConstants[i].getValue()); + } + + } + return Either.left(resourceTypes); + } + + @Override + public Either getNewCategoryData(String name, + NodeTypeEnum type, Class clazz) { + if (name != null) { + String categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), name); + Either, TitanOperationStatus> either = titanGenericDao.getByCriteria(type, props, clazz); + + if (either.isRight()) { + TitanOperationStatus titanOperationStatus = either.right().value(); + log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name()); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } else { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + return Either.left((CategoryData) either.left().value().get(0)); + } else { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java new file mode 100644 index 0000000000..35541e6d46 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.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.be.model.operations.impl; + +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.model.Resource; +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.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("graph-lock-operation") +public class GraphLockOperation implements IGraphLockOperation { + private static Logger log = LoggerFactory.getLogger(ResourceOperation.class.getName()); + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @javax.annotation.Resource + private ResourceOperation resourceOperation; + + @javax.annotation.Resource + private ICacheMangerOperation cacheManagerOperation; + + public GraphLockOperation() { + super(); + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.model.operations.impl.IGraphLockOperation# + * lockResource(java.lang.String, + * org.openecomp.sdc.be.model.operations.api.IResourceOperation) + */ + @Override + public StorageOperationStatus lockComponent(String componentId, NodeTypeEnum nodeType) { + log.info("lock resource with id {}", componentId); + TitanOperationStatus lockElementStatus = null; + try { + + // SET LAST UPDATE DATE OF THE COMPONENT. + // In this way we mark the component as updated one (and component + // won't be fetched from cache since the component in cache has + // different timestamp) + Either updateTime = updateModificationTimeOfComponent( + componentId, nodeType); + if (updateTime.isRight()) { + TitanOperationStatus operationStatus = updateTime.right().value(); + if (operationStatus != TitanOperationStatus.OK) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus); + } + } + + lockElementStatus = titanGenericDao.lockElement(componentId, nodeType); + + } catch (Exception e) { + lockElementStatus = TitanOperationStatus.ALREADY_LOCKED; + + } + + return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus); + + } + + /** + * update the last update date of the component + * + * @param componentId + * @param nodeType + * @return + */ + private Either updateModificationTimeOfComponent(String componentId, + NodeTypeEnum nodeType) { + + if (nodeType == NodeTypeEnum.Resource || nodeType == NodeTypeEnum.Service || nodeType == NodeTypeEnum.Product) { + // We fetch all node since update only timestamp make problems since + // there is default resource type (VFC) which changes component + // resource type when we update only timestamp(ResourceMetadataData + // contains default value VFC on resourceType field). + Either findComp = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, ComponentMetadataData.class); + + if (findComp.isRight()) { + return Either.right(findComp.right().value()); + } + ComponentMetadataData componentMetadataData = findComp.left().value(); + componentMetadataData.getMetadataDataDefinition().setLastUpdateDate(System.currentTimeMillis()); + Either updateNode = titanGenericDao + .updateNode(componentMetadataData, ComponentMetadataData.class); + return updateNode; + } + return Either.right(TitanOperationStatus.OK); + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.model.operations.impl.IGraphLockOperation# + * unlockResource(java.lang.String, + * org.openecomp.sdc.be.model.operations.api.IResourceOperation) + */ + @Override + public StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType) { + + Either addComponentToCachePart1 = addComponentToCachePart1WithoutCommit( + componentId, nodeType); + + TitanOperationStatus lockElementStatus = titanGenericDao.releaseElement(componentId, nodeType); + + if (addComponentToCachePart1.isLeft()) { + Long lastUpdateDate = addComponentToCachePart1.left().value(); + addComponentToCachePart2(componentId, lastUpdateDate, nodeType); + } + + return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus); + } + + private ResourceMetadataData getResourceMetaDataFromResource(Resource resource) { + ResourceMetadataData resourceData = new ResourceMetadataData((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()); + return resourceData; + } + + @Override + public StorageOperationStatus unlockComponentByName(String name, String componentId, NodeTypeEnum nodeType) { + + Either addComponentToCachePart1 = addComponentToCachePart1WithoutCommit( + componentId, nodeType); + + TitanOperationStatus lockElementStatus = titanGenericDao.releaseElement(name, nodeType); + + if (addComponentToCachePart1.isLeft()) { + Long lastUpdateDate = addComponentToCachePart1.left().value(); + addComponentToCachePart2(componentId, lastUpdateDate, nodeType); + } + + return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus); + } + + /** + * We fetch the last update date of the component + * + * @param componentId + * @param nodeType + * @return + */ + private Either addComponentToCachePart1WithoutCommit(String componentId, + NodeTypeEnum nodeType) { + if (componentId != null) { // In case of error, the componentId might be + // empty. + if (nodeType == NodeTypeEnum.Resource || nodeType == NodeTypeEnum.Service + || nodeType == NodeTypeEnum.Product) { + Long lastUpdateDate = null; + Either resResult = resourceOperation + .getComponentByLabelAndId(componentId, nodeType, ComponentMetadataData.class); + if (resResult.isLeft()) { + ComponentMetadataData resourceMetadataData = resResult.left().value(); + lastUpdateDate = resourceMetadataData.getMetadataDataDefinition().getLastUpdateDate(); + + return Either.left(lastUpdateDate); + } else { + return Either.right(resResult.right().value()); + } + } + } + return Either.right(StorageOperationStatus.OPERATION_NOT_SUPPORTED); + } + + /** + * add the component to the cache + * + * @param componentId + * @param lastUpdateDate + * @param nodeType + * @return + */ + private Either addComponentToCachePart2(String componentId, Long lastUpdateDate, + NodeTypeEnum nodeType) { + if (componentId != null) { // In case of error, the componentId might be + // empty. + if (nodeType == NodeTypeEnum.Resource || nodeType == NodeTypeEnum.Service + || nodeType == NodeTypeEnum.Product) { + // add task to Q + log.debug("Going to add component {} of type {} to cache", componentId, nodeType.name().toLowerCase()); + cacheManagerOperation.updateComponentInCache(componentId, lastUpdateDate, nodeType); + } + } + return Either.right(StorageOperationStatus.OPERATION_NOT_SUPPORTED); + } + + @Override + public StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType) { + log.info("lock resource with name {}", name); + TitanOperationStatus lockElementStatus = null; + try { + + lockElementStatus = titanGenericDao.lockElement(name, nodeType); + + } catch (Exception e) { + lockElementStatus = TitanOperationStatus.ALREADY_LOCKED; + + } + + return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus); + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java new file mode 100644 index 0000000000..9312be45c1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java @@ -0,0 +1,2093 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.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.stream.Collectors; + +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.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +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.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +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.GroupTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.operations.api.IGroupOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.GroupData; +import org.openecomp.sdc.be.resources.data.GroupTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("group-operation") +public class GroupOperation extends AbstractOperation implements IGroupOperation { + + private static String ADDING_GROUP = "AddingGroup"; + private static String DELETING_GROUP = "DeletingGroup"; + private static String DELETING_ALL_GROUPS = "DeletingAllGroups"; + private static String ASSOCIATING_GROUP_TO_COMP_INST = "AssociatingGroupToComponentInstance"; + + private static Logger log = LoggerFactory.getLogger(GroupOperation.class.getName()); + + @javax.annotation.Resource + private PropertyOperation propertyOperation; + + @javax.annotation.Resource + private GroupTypeOperation groupTypeOperation; + + @javax.annotation.Resource + private ApplicationDataTypeCache dataTypeCache; + + @Override + public Either addGroupToGraph(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition) { + + String groupTypeUid = groupDefinition.getTypeUid(); + + if (groupTypeUid == null) { + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, "Group type id is empty", + ErrorSeverity.ERROR); + return Either.right(TitanOperationStatus.INVALID_ID); + } + + ComponentMetadataData metaData = null; + if (nodeTypeEnum == NodeTypeEnum.Resource) { + metaData = new ResourceMetadataData(); + } else { + metaData = new ServiceMetadataData(); + } + metaData.getMetadataDataDefinition().setUniqueId(componentId); + + groupDefinition.setUniqueId(UniqueIdBuilder.buildGroupUniqueId(componentId, groupDefinition.getName())); + + int propertiesSize = groupDefinition.getProperties() == null ? 0 : groupDefinition.getProperties().size(); + groupDefinition.setPropertyValueCounter(propertiesSize); + + GroupData groupData = new GroupData(groupDefinition); + + TitanOperationStatus status = null; + // Adding group data node to graph + log.debug("Before adding group to graph {}", groupData.toString()); + Either createNodeResult = titanGenericDao.createNode(groupData, + GroupData.class); + log.debug("After adding group to graph {}", groupData.toString()); + if (createNodeResult.isRight()) { + status = createNodeResult.right().value(); + log.error("Failed to add group {} to graph. Status is {}", groupDefinition.getName(), status); + return Either.right(status); + } + + // Associate group to group type + log.debug("Going to associate group {} to its groupType {}", groupDefinition.getName(), groupDefinition.getType()); + Either associateGroupTypeRes = associateGroupToGroupType(groupData, + groupTypeUid); + log.debug("After associating group {} to its groupType {}. Status is {}", groupDefinition.getName(), groupDefinition.getType(), associateGroupTypeRes); + if (associateGroupTypeRes.isRight()) { + status = associateGroupTypeRes.right().value(); + String description = "Failed to associate group " + groupDefinition.getName() + " to its groupType " + + groupDefinition.getType() + " in graph."; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + // Associate group to component RESOURCE/SERVICE/PRODUCT + Either associateComponentRes = associateGroupToComponent(groupData, + nodeTypeEnum, componentId); + if (associateComponentRes.isRight()) { + status = associateComponentRes.right().value(); + String description = "Failed to associate group " + groupDefinition.getName() + " to " + + nodeTypeEnum.getName() + " " + componentId + ". status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + Either groupTypeRes = groupTypeOperation + .getGroupTypeByUid(groupDefinition.getTypeUid()); + if (groupTypeRes.isRight()) { + TitanOperationStatus operationStatus = groupTypeRes.right().value(); + log.debug("Failed to find group type {}", groupDefinition.getTypeUid()); + if (operationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + } + GroupTypeDefinition groupTypeDefinition = groupTypeRes.left().value(); + // 1. find properties from group type + List groupTypeProperties = groupTypeDefinition.getProperties(); + + // 2. check the properties exists in the group type. + // 3. add parent unique id to the properties + // 4. add node per group property which the group point to it and it + // points to the parent unique id + + // Adding properties to group + List properties = groupDefinition.getProperties(); + + if (properties != null && false == properties.isEmpty()) { + + if (groupTypeProperties == null || true == groupTypeProperties.isEmpty()) { + BeEcompErrorManager.getInstance().logInvalidInputError(ADDING_GROUP, + "group type does not have properties", ErrorSeverity.INFO); + return Either.right(TitanOperationStatus.MATCH_NOT_FOUND); + } + + Map groupTypePropertiesMap = groupTypeProperties.stream() + .collect(Collectors.toMap(p -> p.getName(), p -> p)); + + Either addPropertyResult = null; + int i = 1; + for (GroupProperty prop : properties) { + addPropertyResult = addPropertyToGroup(groupData, prop, groupTypePropertiesMap.get(prop.getName()), i); + if (addPropertyResult.isRight()) { + status = addPropertyResult.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + " to property " + + prop.getName() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + i++; + } + } + + // Associate artifacts to group + List artifacts = groupDefinition.getArtifacts(); + + Either associateArtifactsToGroupOnGraph = associateArtifactsToGroupOnGraph( + groupData.getGroupDataDefinition().getUniqueId(), artifacts); + if (associateArtifactsToGroupOnGraph.isRight() + && associateArtifactsToGroupOnGraph.right().value() != TitanOperationStatus.OK) { + return Either.right(status); + } + /* + * Either addArtifactsRefResult = + * null; if (artifacts != null) { for (String artifactId : artifacts) { + * Either findArtifactRes = + * titanGenericDao .getNode(UniqueIdBuilder + * .getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, + * ArtifactData.class); if (findArtifactRes.isRight()) { status = + * findArtifactRes.right().value(); if (status == + * TitanOperationStatus.NOT_FOUND) { status = + * TitanOperationStatus.INVALID_ID; } String description = + * "Failed to associate group " + groupData.getUniqueId() + + * " to artifact " + artifactId + " in graph. Status is " + status; + * BeEcompErrorManager.getInstance().logInternalFlowError( ADDING_GROUP, + * description, ErrorSeverity.ERROR); return Either.right(status); } + * + * Map props = new HashMap(); + * props.put(GraphPropertiesDictionary.NAME.getProperty(), + * findArtifactRes.left().value().getLabel()); + * + * addArtifactsRefResult = titanGenericDao.createRelation( groupData, + * findArtifactRes.left().value(), GraphEdgeLabels.GROUP_ARTIFACT_REF, + * props); + * + * if (addArtifactsRefResult.isRight()) { status = + * addArtifactsRefResult.right().value(); String description = + * "Failed to associate group " + groupData.getUniqueId() + + * " to artifact " + artifactId + " in graph. Status is " + status; + * BeEcompErrorManager.getInstance().logInternalFlowError( ADDING_GROUP, + * description, ErrorSeverity.ERROR); return Either.right(status); } } } + */ + + // Associate group to members + // map of componentInstances + Map members = groupDefinition.getMembers(); + + if (members != null && false == members.isEmpty()) { + Either addMembersRefResult = null; + for (Entry member : members.entrySet()) { + if (member.getValue() == null || member.getValue().isEmpty()) { + continue; + } + Either findComponentInstanceRes = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), member.getValue(), + ComponentInstanceData.class); + if (findComponentInstanceRes.isRight()) { + status = findComponentInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to find to find member of group " + member.getValue() + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), member.getKey()); + addMembersRefResult = titanGenericDao.createRelation(groupData, findComponentInstanceRes.left().value(), + GraphEdgeLabels.GROUP_MEMBER, props); + + if (addMembersRefResult.isRight()) { + status = addMembersRefResult.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + + " to component instance " + member.getValue() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + } + } + + return Either.left(groupData); + } + + private Either addPropertyToGroup(GroupData groupData, + GroupProperty groupProperty, PropertyDefinition prop, Integer index) { + + if (prop == null) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + + String propertyId = prop.getUniqueId(); + Either findPropertyDefRes = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + PropertyData propertyData = findPropertyDefRes.left().value(); + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + String value = groupProperty.getValue(); + + Either checkInnerType = propertyOperation.checkInnerType(propDataDef); + if (checkInnerType.isRight()) { + TitanOperationStatus status = checkInnerType.right().value(); + return Either.right(status); + } + + String innerType = checkInnerType.left().value(); + + Either, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", + "Failed to add property to group. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + + } + + log.debug("Before validateAndUpdatePropertyValue"); + Either isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, + innerType, allDataTypes.left().value()); + log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid); + + String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + } + + String uniqueId = UniqueIdBuilder.buildGroupPropertyValueUid((String) groupData.getUniqueId(), index); + PropertyValueData propertyValueData = new PropertyValueData(); + propertyValueData.setUniqueId(uniqueId); + propertyValueData.setValue(newValue); + + log.debug("Before adding property value to graph {}",propertyValueData); + Either createNodeResult = titanGenericDao.createNode(propertyValueData, + PropertyValueData.class); + log.debug("After adding property value to graph {}", propertyValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + return Either.right(operationStatus); + } + + Either createRelResult = titanGenericDao.createRelation(propertyValueData, + propertyData, GraphEdgeLabels.PROPERTY_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + String description = "Failed to associate property value " + uniqueId + " to property " + propertyId + + " in graph. status is " + operationStatus; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } + + createRelResult = titanGenericDao.createRelation(groupData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, + null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + String description = "Failed to associate group " + groupData.getGroupDataDefinition().getName() + + " to property value " + uniqueId + " in graph. Status is " + operationStatus; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + } + + private Either associateGroupToComponent(GroupData groupData, + NodeTypeEnum nodeTypeEnum, String componentId) { + UniqueIdData componentIdData = new UniqueIdData(nodeTypeEnum, componentId); + + log.debug("Before associating component {} to group {}.", componentId, groupData); + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), groupData.getGroupDataDefinition().getName()); + Either createRelResult = titanGenericDao.createRelation(componentIdData, + groupData, GraphEdgeLabels.GROUP, props); + log.debug("After associating component {} to group {}. Status is {}", componentId, groupData, createRelResult); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.debug("Failed to associate component {} to group {} in graph. Status is {}", componentId, groupData, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createRelResult.left().value()); + } + + private Either associateGroupToGroupType(GroupData groupData, + String groupTypeUid) { + + UniqueIdData groupTypeIdData = new UniqueIdData(NodeTypeEnum.GroupType, groupTypeUid); + + log.debug("Before associating {} to group type {} (uid = {}).", groupData, groupData.getGroupDataDefinition().getType(), groupTypeUid); + Either createRelResult = titanGenericDao.createRelation(groupData, + groupTypeIdData, GraphEdgeLabels.TYPE_OF, null); + + if (log.isDebugEnabled()) { + log.debug("After associating {} to group type {} (uid = {}). Result is {}", groupData, groupData.getGroupDataDefinition().getType(), groupTypeUid, createRelResult); + } + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + return Either.right(operationStatus); + } + return createRelResult; + } + + @Override + public Either addGroup(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition) { + return addGroup(nodeTypeEnum, componentId, groupDefinition, false); + } + + @Override + public Either addGroup(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition, boolean inTransaction) { + + Either result = null; + try { + Either addGroupRes = addGroupToGraph(nodeTypeEnum, componentId, + groupDefinition); + if (addGroupRes.isRight()) { + TitanOperationStatus status = addGroupRes.right().value(); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + + GroupData groupData = addGroupRes.left().value(); + String groupUid = groupData.getGroupDataDefinition().getUniqueId(); + result = this.getGroup(groupUid, true); + + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph. Failed to add group {} to {}", groupDefinition.getName(), nodeTypeEnum.toString()); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private GroupDefinition convertGroupDataToGroupDefinition(GroupData groupData) { + GroupDefinition newGroupDefinition = new GroupDefinition(groupData.getGroupDataDefinition()); + return newGroupDefinition; + } + + public Either getGroup(String uniqueId) { + return getGroup(uniqueId, false); + } + + @Override + public Either getGroup(String uniqueId, boolean inTransaction) { + + Either result = null; + + try { + + Either groupFromGraph = this.getGroupFromGraph(uniqueId); + + if (groupFromGraph.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + log.debug("Failed to retrieve group {} from graph. Status is {}", uniqueId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + GroupDefinition groupDefinition = groupFromGraph.left().value(); + result = Either.left(groupDefinition); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either getGroupFromGraph(String uniqueId) { + + return getGroupFromGraph(uniqueId, false, false, false); + + } + + /** + * get the list of artifacts related to a given group + * + * @param groupUniqueId + * @return + */ + // private Either, TitanOperationStatus> getGroupArtifacts( + // String groupUniqueId) { + // + // Either, TitanOperationStatus> result = null; + // + // Either>, + // TitanOperationStatus> childrenNodes = titanGenericDao + // .getChildrenNodes( + // UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), + // groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF, + // NodeTypeEnum.ArtifactRef, ArtifactData.class); + // if (childrenNodes.isRight()) { + // TitanOperationStatus status = childrenNodes.right().value(); + // if (status == TitanOperationStatus.NOT_FOUND) { + // status = TitanOperationStatus.OK; + // } + // result = Either.right(status); + // + // } else { + // + // List artifactsList = new ArrayList<>(); + // List> list = childrenNodes + // .left().value(); + // if (list != null) { + // for (ImmutablePair pair : list) { + // ArtifactData artifactData = pair.getKey(); + // String uniqueId = artifactData.getArtifactDataDefinition() + // .getUniqueId(); + // artifactsList.add(uniqueId); + // } + // } + // + // log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList); + // result = Either.left(artifactsList); + // } + // + // return result; + // + // } + + /** + * get members of group + * + * @param groupUniqueId + * @return + */ + protected Either, TitanOperationStatus> getGroupMembers(String groupUniqueId) { + + Either, TitanOperationStatus> result = null; + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, + GraphEdgeLabels.GROUP_MEMBER, NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(status); + + } else { + + Map compInstaMap = new HashMap<>(); + List> list = childrenNodes.left().value(); + if (list != null) { + for (ImmutablePair pair : list) { + ComponentInstanceData componentInstanceData = pair.getKey(); + + String compInstUniqueId = componentInstanceData.getComponentInstDataDefinition().getUniqueId(); + String compInstName = componentInstanceData.getName(); + compInstaMap.put(compInstName, compInstUniqueId); + } + } + + result = Either.left(compInstaMap); + } + + return result; + } + + public Either getGroupTypeOfGroup(String groupUniqueId) { + + Either, TitanOperationStatus> groupTypeRes = titanGenericDao.getChild( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.TYPE_OF, + NodeTypeEnum.GroupType, GroupTypeData.class); + + if (groupTypeRes.isRight()) { + TitanOperationStatus status = groupTypeRes.right().value(); + log.debug("Cannot find group type associated with capability {}. Status is {}", groupUniqueId, status); + + BeEcompErrorManager.getInstance().logBeFailedFindAssociationError("Fetch Group type", + NodeTypeEnum.GroupType.getName(), groupUniqueId, String.valueOf(status)); + return Either.right(groupTypeRes.right().value()); + } + + GroupTypeData groupTypeData = groupTypeRes.left().value().getKey(); + + Either groupTypeByUid = groupTypeOperation + .getGroupTypeByUid(groupTypeData.getGroupTypeDataDefinition().getUniqueId()); + + return groupTypeByUid; + + } + + /** + * get all properties of the group. + * + * the propert definition is taken from the group type. + * + * @param groupUid + * @return + */ + public Either, TitanOperationStatus> getGroupProperties(String groupUid) { + + List groupPropertiesList = new ArrayList<>(); + + Either groupTypeOfGroupRes = getGroupTypeOfGroup(groupUid); + + if (groupTypeOfGroupRes.isRight()) { + TitanOperationStatus status = groupTypeOfGroupRes.right().value(); + return Either.right(status); + } + + GroupTypeDefinition groupTypeDefinition = groupTypeOfGroupRes.left().value(); + + // Get the properties on the group type of this group + List groupTypeProperties = groupTypeDefinition.getProperties(); + + if (groupTypeProperties == null || true == groupTypeProperties.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + Map uidToPropDefMap = groupTypeProperties.stream() + .collect(Collectors.toMap(p -> p.getUniqueId(), p -> p)); + + // Find all properties values on the group + Either>, TitanOperationStatus> propertyImplNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUid, + GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, PropertyValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + groupPropertiesList = groupTypeProperties.stream() + .map(p -> new GroupProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList()); + return Either.left(groupPropertiesList); + } else { + return Either.right(status); + } + } + + List> list = propertyImplNodes.left().value(); + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + List processedProps = new ArrayList<>(); + + for (ImmutablePair propertyValue : list) { + + PropertyValueData propertyValueData = propertyValue.getLeft(); + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either, TitanOperationStatus> propertyDefRes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, + GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair propertyDefPair = propertyDefRes.left().value(); + + PropertyData propertyData = propertyDefPair.left; + String propertyUniqueId = propertyData.getPropertyDataDefinition().getUniqueId(); + + PropertyDefinition propertyDefinition = uidToPropDefMap.get(propertyUniqueId); + GroupProperty groupProperty = new GroupProperty(propertyDefinition, value, propertyValueUid); + + processedProps.add(propertyUniqueId); + + groupPropertiesList.add(groupProperty); + + } + + // Find all properties which does not have property value on the group. + List leftProps = groupTypeProperties.stream() + // filter out the group type properties which already processed + .filter(p -> false == processedProps.contains(p.getUniqueId())) + .map(p -> new GroupProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList()); + if (leftProps != null) { + groupPropertiesList.addAll(leftProps); + } + + return Either.left(groupPropertiesList); + } + + public Either, TitanOperationStatus> getAllGroupsFromGraph(String componentId, + NodeTypeEnum componentTypeEnum) { + + return getAllGroupsFromGraph(componentId, componentTypeEnum, false, false, false); + + } + + @Override + public Either, StorageOperationStatus> getAllGroups(String componentId, + NodeTypeEnum compTypeEnum, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + try { + + Either, TitanOperationStatus> allGroups = this.getAllGroupsFromGraph(componentId, + compTypeEnum); + + if (allGroups.isRight()) { + TitanOperationStatus status = allGroups.right().value(); + log.debug("Failed to retrieve all groups of component {} from graph. Status is {}", componentId, + status); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + List groupsDefinition = allGroups.left().value(); + result = Either.left(groupsDefinition); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either, StorageOperationStatus> getAllGroups(String componentId, + NodeTypeEnum compTypeEnum) { + return getAllGroups(componentId, compTypeEnum, false); + } + + public Either deleteGroupFromGraph(String groupUniqueId) { + + Either groupFromGraph = this.getGroupFromGraph(groupUniqueId); + if (groupFromGraph.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + log.debug("Cannot find group {} on graph. Status is {}", groupUniqueId, status); + return Either.right(status); + } + + GroupDefinition groupDefinition = groupFromGraph.left().value(); + // 1. delete all properties values nodes + List properties = groupDefinition.getProperties(); + if (properties != null) { + for (GroupProperty groupProperty : properties) { + String propValueUniqueId = groupProperty.getValueUniqueUid(); + + if (propValueUniqueId != null) { + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.PropertyValue, propValueUniqueId); + Either deleteNode = titanGenericDao + .deleteNode(uniqueIdData, PropertyValueData.class); + if (deleteNode.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + String description = String.format( + "Failed to delete property {} under group {}" + groupUniqueId + + " on graph. Status is {}", + propValueUniqueId, groupDefinition.getName(), status.name()); + log.debug(description); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError(DELETING_GROUP, propValueUniqueId, + status.name()); + return Either.right(status); + } else { + log.trace("Property {} was deleted from geoup {}", propValueUniqueId, groupDefinition.getName()); + } + } + } + } + + // 2. delete the group node + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.Group, groupUniqueId); + Either deleteNode = titanGenericDao.deleteNode(uniqueIdData, GroupData.class); + if (deleteNode.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + String description = String.format( + "Failed to delete group {} with uid " + groupUniqueId + " on graph. Status is {}", + groupDefinition.getName(), groupUniqueId, status.name()); + log.debug(description); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError(DELETING_GROUP, groupUniqueId, status.name()); + return Either.right(status); + } else { + log.trace("Group {} was deleted from group", groupUniqueId); + } + + GroupData groupData = deleteNode.left().value(); + return Either.left(groupData); + } + + public Either deleteGroup(String groupUniqueId) { + return deleteGroup(groupUniqueId, false); + } + + public Either deleteGroup(String groupUniqueId, boolean inTransaction) { + + Either result = null; + + try { + + Either deleteGroup = this.deleteGroupFromGraph(groupUniqueId); + + if (deleteGroup.isRight()) { + TitanOperationStatus status = deleteGroup.right().value(); + log.debug("Failed to delete group {} from graph. Status is ", groupUniqueId, status.name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + GroupData groupData = deleteGroup.left().value(); + GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData); + result = Either.left(groupDefinition); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either, TitanOperationStatus> deleteAllGroupsFromGraph(String componentId, + NodeTypeEnum componentTypeEnum) { + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(componentTypeEnum), componentId, + GraphEdgeLabels.GROUP, NodeTypeEnum.Group, GroupData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logBeFailedFindAllNodesError(DELETING_ALL_GROUPS, + NodeTypeEnum.Group.name(), componentId, status.name()); + } + return Either.right(status); + } + + List result = new ArrayList<>(); + + List> list = childrenNodes.left().value(); + if (list != null) { + for (ImmutablePair pair : list) { + String uniqueId = pair.left.getGroupDataDefinition().getUniqueId(); + Either deleteGroupFromGraph = deleteGroupFromGraph(uniqueId); + if (deleteGroupFromGraph.isRight()) { + TitanOperationStatus status = deleteGroupFromGraph.right().value(); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError(DELETING_ALL_GROUPS, uniqueId, + status.name()); + return Either.right(status); + } + GroupData groupData = deleteGroupFromGraph.left().value(); + GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData); + result.add(groupDefinition); + } + } + + return Either.left(result); + } + + @Override + public Either, StorageOperationStatus> deleteAllGroups(String componentId, + NodeTypeEnum compTypeEnum, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + try { + + Either, TitanOperationStatus> allGroups = this.deleteAllGroupsFromGraph(componentId, + compTypeEnum); + + if (allGroups.isRight()) { + TitanOperationStatus status = allGroups.right().value(); + log.debug("Failed to delete all groups of component {} from graph. Status is {}", componentId, status); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + List groupsDefinition = allGroups.left().value(); + result = Either.left(groupsDefinition); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either, StorageOperationStatus> deleteAllGroups(String componentId, + NodeTypeEnum compTypeEnum) { + return deleteAllGroups(componentId, compTypeEnum, false); + } + + public Either, StorageOperationStatus> prepareGroupsForCloning( + org.openecomp.sdc.be.model.Component origResource, + ImmutablePair, Map> cloneInstances) { + + List groupsToCreate = new ArrayList<>(); + Either, StorageOperationStatus> result = Either.left(groupsToCreate); + + List groups = origResource.getGroups(); + + if (groups != null) { + // keep typeUid + // keep artifacts uids + // remove properties without valueUniqueId + for (GroupDefinition groupDefinition : groups) { + + GroupDefinition gdToCreate = new GroupDefinition(groupDefinition); + gdToCreate.setUniqueId(null); + gdToCreate.setMembers(null); + + List properties = groupDefinition.getProperties(); + if (properties != null) { + // Take properties which was updated in the + // group(getValueUniqueUid != null), + // Then set null instead of the value(prepare for the + // creation). + List propertiesToUpdate = properties.stream() + .filter(p -> p.getValueUniqueUid() != null).map(p -> { + p.setValueUniqueUid(null); + return p; + }).collect(Collectors.toList()); + + gdToCreate.setProperties(propertiesToUpdate); + + } + + Map members = groupDefinition.getMembers(); + if (cloneInstances != null) { + List createdInstances = cloneInstances.left; + Map oldCompUidToNew = cloneInstances.right; + if (members != null && createdInstances != null) { + + Map compInstIdToName = createdInstances.stream() + .collect(Collectors.toMap(p -> p.getUniqueId(), p -> p.getName())); + + Map membersToCreate = new HashMap<>(); + + for (String oldCompInstId : members.values()) { + String newCompInstUid = oldCompUidToNew.get(oldCompInstId); + if (newCompInstUid == null) { + result = Either.right(StorageOperationStatus.MATCH_NOT_FOUND); + return result; + } + String newCompInstName = compInstIdToName.get(newCompInstUid); + membersToCreate.put(newCompInstName, newCompInstUid); + } + + gdToCreate.setMembers(membersToCreate); + } + } + + log.debug("The group definition for creation is {}", gdToCreate); + + groupsToCreate.add(gdToCreate); + } + + } + + return result; + } + + @Override + public Either, StorageOperationStatus> addGroups(NodeTypeEnum nodeTypeEnum, + String componentId, List groups, boolean inTransaction) { + + List createdGroups = new ArrayList<>(); + + Either, StorageOperationStatus> result = null; + + try { + + if (groups != null) { + for (GroupDefinition groupDefinition : groups) { + Either addGroup = this.addGroup(nodeTypeEnum, componentId, + groupDefinition, true); + if (addGroup.isRight()) { + StorageOperationStatus status = addGroup.right().value(); + result = Either.right(status); + return result; + } + + createdGroups.add(addGroup.left().value()); + } + } + + result = Either.left(createdGroups); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + @Override + public Either, TitanOperationStatus> getAssociatedGroupsToComponentInstanceFromGraph( + String componentInstanceId) { + + List groups = new ArrayList<>(); + Either, TitanOperationStatus> result = Either.left(groups); + + Either>, TitanOperationStatus> parentNodes = titanGenericDao + .getParentNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), componentInstanceId, + GraphEdgeLabels.GROUP_MEMBER, NodeTypeEnum.Group, GroupData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus status = parentNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logBeFailedFindParentError("FetchGroupMembers", componentInstanceId, + status.name()); + } + return Either.right(status); + } + + List> fetchedGroups = parentNodes.left().value(); + if (fetchedGroups != null) { + List list = fetchedGroups.stream().map(p -> p.left.getGroupDataDefinition().getUniqueId()) + .collect(Collectors.toList()); + groups.addAll(list); + } + + return result; + + } + + @Override + public Either, StorageOperationStatus> getAssociatedGroupsToComponentInstance( + String componentInstanceId, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + try { + + Either, TitanOperationStatus> groups = this + .getAssociatedGroupsToComponentInstanceFromGraph(componentInstanceId); + + if (groups.isRight()) { + TitanOperationStatus status = groups.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List list = groups.left().value(); + + return Either.left(list); + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either, StorageOperationStatus> getAssociatedGroupsToComponentInstance( + String componentInstanceId) { + return getAssociatedGroupsToComponentInstance(componentInstanceId, false); + } + + @Override + public Either, TitanOperationStatus> associateGroupsToComponentInstanceOnGraph( + List groups, String componentInstanceId, String compInstName) { + + List relations = new ArrayList<>(); + Either, TitanOperationStatus> result = Either.left(relations); + + if (groups != null && false == groups.isEmpty()) { + + UniqueIdData compInstData = new UniqueIdData(NodeTypeEnum.ResourceInstance, componentInstanceId); + + for (String groupId : groups) { + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), compInstName); + Either createRelation = titanGenericDao.createRelation(groupData, + compInstData, GraphEdgeLabels.GROUP_MEMBER, props); + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + + " to component instance " + compInstName + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ASSOCIATING_GROUP_TO_COMP_INST, description, + ErrorSeverity.ERROR); + result = Either.right(status); + break; + } + GraphRelation graphRelation = createRelation.left().value(); + relations.add(graphRelation); + } + } else { + result = Either.right(TitanOperationStatus.OK); + } + + return result; + } + + public StorageOperationStatus associateGroupsToComponentInstance(List groups, String componentInstanceId, + String compInstName) { + + return associateGroupsToComponentInstance(groups, componentInstanceId, compInstName, false); + } + + @Override + public StorageOperationStatus associateGroupsToComponentInstance(List groups, String componentInstanceId, + String compInstName, boolean inTransaction) { + + StorageOperationStatus result = null; + + try { + Either, TitanOperationStatus> either = this + .associateGroupsToComponentInstanceOnGraph(groups, componentInstanceId, compInstName); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return result; + } + + result = StorageOperationStatus.OK; + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result != StorageOperationStatus.OK) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either, TitanOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, + NodeTypeEnum componentTypeEnum, String artifactId) { + + List relations = new ArrayList<>(); + Either, TitanOperationStatus> result = Either.left(relations); + + Either, TitanOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, + componentTypeEnum, true, true, false); + if (allGroupsFromGraph.isRight()) { + TitanOperationStatus status = allGroupsFromGraph.right().value(); + return Either.right(status); + } + + List allGroups = allGroupsFromGraph.left().value(); + if (allGroups == null || allGroups.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + // Find all groups which contains this artifact id + List associatedGroups = allGroups.stream() + .filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(artifactId)) + .collect(Collectors.toList()); + + if (associatedGroups != null && false == associatedGroups.isEmpty()) { + log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(p -> p.getName()).collect(Collectors.toList()), artifactId); + + UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId); + for (GroupDefinition groupDefinition : associatedGroups) { + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId()); + Either deleteRelation = titanGenericDao.deleteRelation(groupData, + artifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF); + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + relations.add(deleteRelation.left().value()); + } + + return result; + + } else { + log.debug("No group under component id {} is associated to artifact {}", componentId, artifactId); + return Either.right(TitanOperationStatus.OK); + } + + } + + public Either getGroupFromGraph(String uniqueId, boolean skipProperties, + boolean skipMembers, boolean skipArtifacts) { + + Either result = null; + + Either groupRes = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), uniqueId, GroupData.class); + if (groupRes.isRight()) { + TitanOperationStatus status = groupRes.right().value(); + log.debug("Failed to retrieve group {} from graph. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Group", uniqueId, + String.valueOf(status)); + result = Either.right(status); + return result; + } + + GroupData groupData = groupRes.left().value(); + + GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData); + + Either groupTypeOfGroup = getGroupTypeOfGroup(uniqueId); + + if (groupTypeOfGroup.isRight()) { + TitanOperationStatus status = groupTypeOfGroup.right().value(); + log.debug("Failed to retrieve capability type of capability {}. Status is {}", uniqueId, status); + + result = Either.right(status); + return result; + } + + GroupTypeDefinition groupTypeDefinition = groupTypeOfGroup.left().value(); + + groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId()); + + if (false == skipMembers) { + Either, TitanOperationStatus> membersRes = getGroupMembers(uniqueId); + if (membersRes.isRight()) { + TitanOperationStatus status = membersRes.right().value(); + if (status != TitanOperationStatus.OK) { + result = Either.right(status); + return result; + } + } else { + Map members = membersRes.left().value(); + groupDefinition.setMembers(members); + } + } + + if (false == skipProperties) { + Either, TitanOperationStatus> propertiesRes = getGroupProperties(uniqueId); + if (propertiesRes.isRight()) { + TitanOperationStatus status = propertiesRes.right().value(); + if (status != TitanOperationStatus.OK) { + result = Either.right(status); + return result; + } + } else { + List properties = propertiesRes.left().value(); + groupDefinition.setProperties(properties); + } + } + + if (false == skipArtifacts) { + Either>, TitanOperationStatus> artifactsRes = getGroupArtifactsPairs( + uniqueId); + if (artifactsRes.isRight()) { + TitanOperationStatus status = artifactsRes.right().value(); + if (status != TitanOperationStatus.OK) { + result = Either.right(status); + return result; + } + } else { + List artifactsUid = new ArrayList<>(); + List artifactsUUID = new ArrayList<>(); + + List> list = artifactsRes.left().value(); + if (list != null) { + for (ImmutablePair pair : list) { + String uid = pair.left; + String UUID = pair.right; + artifactsUid.add(uid); + artifactsUUID.add(UUID); + } + groupDefinition.setArtifacts(artifactsUid); + groupDefinition.setArtifactsUuid(artifactsUUID); + } + } + } + result = Either.left(groupDefinition); + + return result; + + } + + @Override + public boolean isGroupExist(String groupName, boolean inTransaction) { + + Either, TitanOperationStatus> eitherGroup = null; + try { + Map properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NAME.getProperty(), groupName); + + eitherGroup = titanGenericDao.getByCriteria(NodeTypeEnum.Group, properties, GroupData.class); + return eitherGroup.isLeft() && !eitherGroup.left().value().isEmpty(); + + } finally { + handleTransactionCommitRollback(inTransaction, eitherGroup); + } + } + + protected Either, TitanOperationStatus> getAllGroupsFromGraph(String componentId, + NodeTypeEnum componentTypeEnum, boolean skipProperties, boolean skipMembers, boolean skipArtifacts) { + + List groups = new ArrayList(); + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(componentTypeEnum), componentId, + GraphEdgeLabels.GROUP, NodeTypeEnum.Group, GroupData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + return Either.right(status); + } + + List> graphGroups = childrenNodes.left().value(); + + if (graphGroups == null || true == graphGroups.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + // Consumer consumer = (x) -> getGroup(x); + // StreamUtils.takeWhile(graphGroups.stream().map(p -> + // p.left.getUniqueId()), consumer); + + for (ImmutablePair pair : graphGroups) { + + String groupUniqueId = pair.left.getGroupDataDefinition().getUniqueId(); + Either groupRes = this.getGroupFromGraph(groupUniqueId, + skipProperties, skipMembers, skipArtifacts); + + if (groupRes.isRight()) { + TitanOperationStatus status = groupRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } else { + groups.add(groupRes.left().value()); + } + + } + + return Either.left(groups); + } + + @Override + public StorageOperationStatus dissociateAllGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId, boolean inTransaction) { + + StorageOperationStatus result = null; + + try { + Either, TitanOperationStatus> either = this + .dissociateAllGroupsFromArtifactOnGraph(componentId, componentTypeEnum, artifactId); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return result; + } + + result = StorageOperationStatus.OK; + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result != StorageOperationStatus.OK) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public StorageOperationStatus dissociateAllGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId) { + + return dissociateAllGroupsFromArtifact(componentId, componentTypeEnum, artifactId, false); + } + + @Override + public TitanOperationStatus dissociateAndAssociateGroupsFromArtifactOnGraph(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) { + + Either, TitanOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, + componentTypeEnum, true, true, false); + if (allGroupsFromGraph.isRight()) { + TitanOperationStatus status = allGroupsFromGraph.right().value(); + return status; + } + + List allGroups = allGroupsFromGraph.left().value(); + if (allGroups == null || allGroups.isEmpty()) { + return TitanOperationStatus.OK; + } + + // Find all groups which contains this artifact id + List associatedGroups = allGroups.stream() + .filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(oldArtifactId)) + .collect(Collectors.toList()); + + if (associatedGroups != null && false == associatedGroups.isEmpty()) { + + log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(p -> p.getName()).collect(Collectors.toList()), oldArtifactId); + + UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId); + UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, + newArtifact.getArtifactDataDefinition().getUniqueId()); + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel()); + + for (GroupDefinition groupDefinition : associatedGroups) { + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId()); + + Either deleteRelation = titanGenericDao.deleteRelation(groupData, + oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF); + log.trace("After dissociate group {} from artifac {}", groupDefinition.getName(), oldArtifactId); + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return status; + } + + Either createRelation = titanGenericDao.createRelation(groupData, + newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props); + log.trace("After associate group {} to artifact {}", groupDefinition.getName(), newArtifact.getUniqueIdKey()); + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return status; + } + } + + } + return TitanOperationStatus.OK; + } + + @Override + public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction) { + + StorageOperationStatus result = null; + + try { + TitanOperationStatus status = this.dissociateAndAssociateGroupsFromArtifactOnGraph(componentId, + componentTypeEnum, oldArtifactId, newArtifact); + + if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) { + result = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return result; + } + + result = StorageOperationStatus.OK; + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result != StorageOperationStatus.OK) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) { + return dissociateAndAssociateGroupsFromArtifact(componentId, componentTypeEnum, oldArtifactId, newArtifact, + false); + } + + private Either>, TitanOperationStatus> getGroupArtifactsPairs( + String groupUniqueId) { + + Either>, TitanOperationStatus> result = null; + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, + GraphEdgeLabels.GROUP_ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class); + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(status); + + } else { + + List> artifactsList = new ArrayList<>(); + List> list = childrenNodes.left().value(); + if (list != null) { + for (ImmutablePair pair : list) { + ArtifactData artifactData = pair.getKey(); + String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId(); + String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID(); + ImmutablePair artifact = new ImmutablePair(uniqueId, UUID); + artifactsList.add(artifact); + } + } + + log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList); + result = Either.left(artifactsList); + } + + return result; + + } + + public Either, TitanOperationStatus> updateGroupVersionOnGraph(List groupsUniqueId) { + + if (groupsUniqueId != null) { + + List groups = new ArrayList<>(); + for (String groupUid : groupsUniqueId) { + Either either = updateGroupVersionOnGraph(groupUid); + if (either.isRight()) { + log.debug("Failed to update version of group {}", groupUid); + return Either.right(either.right().value()); + } + groups.add(either.left().value()); + } + return Either.left(groups); + } + + return Either.right(TitanOperationStatus.OK); + + } + + /** + * update the group version of a given group. It also creates a new UUID. + * + * @param groupUniqueId + * @return + */ + public Either updateGroupVersionOnGraph(String groupUniqueId) { + + Either groupFromGraph = this.getGroupFromGraph(groupUniqueId, false, + false, false); + + if (groupFromGraph.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + return Either.right(status); + } else { + GroupDefinition groupDefinition = groupFromGraph.left().value(); + String version = groupDefinition.getVersion(); + String newVersion = increaseMajorVersion(version); + Integer pvCounter = groupDefinition.getPropertyValueCounter(); + + GroupData groupData = new GroupData(); + groupData.getGroupDataDefinition().setUniqueId(groupUniqueId); + groupData.getGroupDataDefinition().setVersion(newVersion); + groupData.getGroupDataDefinition().setPropertyValueCounter(pvCounter); + + String groupUUID = UniqueIdBuilder.generateUUID(); + groupData.getGroupDataDefinition().setGroupUUID(groupUUID); + + Either updateNode = titanGenericDao.updateNode(groupData, GroupData.class); + if (updateNode.isRight()) { + return Either.right(updateNode.right().value()); + } else { + groupFromGraph = this.getGroupFromGraph(groupUniqueId, false, false, false); + return groupFromGraph; + } + + } + } + + /** + * The version of the group is an integer. In order to support BC, we might + * get a version in a float format. + * + * @param version + * @return + */ + private String increaseMajorVersion(String version) { + + String[] versionParts = version.split(LifecycleOperation.VERSION_DELIMETER_REGEXP); + Integer majorVersion = Integer.parseInt(versionParts[0]); + + majorVersion++; + + return String.valueOf(majorVersion); + + } + + public Either associateArtifactsToGroupOnGraph(String groupId, + List artifactsId) { + + if (artifactsId == null || artifactsId.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + for (String artifactId : artifactsId) { + Either findArtifactRes = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class); + if (findArtifactRes.isRight()) { + TitanOperationStatus status = findArtifactRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to associate group " + groupId + " to artifact " + artifactId + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), findArtifactRes.left().value().getLabel()); + + GraphNode groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + Either addArtifactsRefResult = titanGenericDao.createRelation( + groupData, findArtifactRes.left().value(), GraphEdgeLabels.GROUP_ARTIFACT_REF, props); + + if (addArtifactsRefResult.isRight()) { + TitanOperationStatus status = addArtifactsRefResult.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + " to artifact " + + artifactId + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + } + + Either groupFromGraph = this.getGroupFromGraph(groupId, true, true, + false); + + return groupFromGraph; + } + + public Either associateMembersToGroupOnGraph(String groupId, + Map members) { + + if (members != null && false == members.isEmpty()) { + Either addMembersRefResult = null; + for (Entry member : members.entrySet()) { + Either findComponentInstanceRes = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), member.getValue(), + ComponentInstanceData.class); + if (findComponentInstanceRes.isRight()) { + + TitanOperationStatus status = findComponentInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to find to find component instance group " + member.getValue() + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), member.getKey()); + GraphNode groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + addMembersRefResult = titanGenericDao.createRelation(groupData, findComponentInstanceRes.left().value(), + GraphEdgeLabels.GROUP_MEMBER, props); + if (addMembersRefResult.isRight()) { + TitanOperationStatus status = addMembersRefResult.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + + " to component instance " + member.getValue() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + } + } + + Either groupFromGraph = this.getGroupFromGraph(groupId, true, false, + true); + + return groupFromGraph; + } + + public Either dissociateArtifactsFromGroupOnGraph(String groupId, + List artifactsId) { + + if (artifactsId == null || artifactsId.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + for (String artifactId : artifactsId) { + + UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.Group, artifactId); + Either deleteRelation = titanGenericDao.deleteRelation(groupData, + artifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF); + log.trace("After dissociate group {} from artifact {}", groupId, artifactId); + + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to diassociate group " + groupId + " from artifact " + artifactId + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + } + + Either groupFromGraph = this.getGroupFromGraph(groupId, true, true, + false); + + return groupFromGraph; + + } + + public Either dissociateMembersFromGroupOnGraph(String groupId, + Map members) { + + if (members == null || members.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + for (Entry member : members.entrySet()) { + + UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.Group, member.getValue()); + Either deleteRelation = titanGenericDao.deleteRelation(groupData, + artifactData, GraphEdgeLabels.GROUP_MEMBER); + log.trace("After dissociate group {} from members", groupId, member.getValue()); + + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to diassociate group " + groupId + " from member " + member.getValue() + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + } + + Either groupFromGraph = this.getGroupFromGraph(groupId, true, true, + false); + + return groupFromGraph; + + } + + /** + * dissociate artifacts from a group. It do not delete the artifacts !!! + * + * @param groupId + * @param artifactsId + * @param inTransaction + * @return + */ + public Either dissociateArtifactsFromGroup(String groupId, + List artifactsId, boolean inTransaction) { + + Either result = null; + + try { + Either titanRes = this.dissociateArtifactsFromGroupOnGraph(groupId, + artifactsId); + + if (titanRes.isRight()) { + StorageOperationStatus storageOperationStatus = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanRes.right().value()); + result = Either.right(storageOperationStatus); + return result; + } + + result = Either.left(titanRes.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either dissociateMembersFromGroup(String groupId, + Map members, boolean inTransaction) { + + Either result = null; + + try { + Either titanRes = this.dissociateMembersFromGroupOnGraph(groupId, + members); + + if (titanRes.isRight()) { + StorageOperationStatus storageOperationStatus = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanRes.right().value()); + result = Either.right(storageOperationStatus); + return result; + } + + result = Either.left(titanRes.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + /** + * Associate artifacts to a given group + * + * @param groupId + * @param artifactsId + * @param inTransaction + * @return + */ + public Either associateArtifactsToGroup(String groupId, + List artifactsId, boolean inTransaction) { + + Either result = null; + + try { + + Either titanRes = this.associateArtifactsToGroupOnGraph(groupId, + artifactsId); + + if (titanRes.isRight()) { + StorageOperationStatus status = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanRes.right().value()); + result = Either.right(status); + } + + result = Either.left(titanRes.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + /** + * Associate artifacts to a given group + * + * @param groupId + * @param artifactsId + * @param inTransaction + * @return + */ + public Either associateMembersToGroup(String groupId, + Map members, boolean inTransaction) { + + Either result = null; + + try { + + Either titanRes = this.associateMembersToGroupOnGraph(groupId, + members); + + if (titanRes.isRight()) { + StorageOperationStatus status = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanRes.right().value()); + result = Either.right(status); + return result; + } + + result = Either.left(titanRes.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either, StorageOperationStatus> updateGroupVersion(List groupsId, + boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + try { + Either, TitanOperationStatus> updateGroupVersionOnGraph = this + .updateGroupVersionOnGraph(groupsId); + + if (updateGroupVersionOnGraph.isRight()) { + result = Either.right(DaoStatusConverter + .convertTitanStatusToStorageStatus(updateGroupVersionOnGraph.right().value())); + return result; + } + + result = Either.left(updateGroupVersionOnGraph.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either updateGroupName(String uniqueId, String newName, + boolean inTransaction) { + Either result = null; + + try { + Either updateGroupNameOnGraph = this.updateGroupNameOnGraph(uniqueId, + newName); + + if (updateGroupNameOnGraph.isRight()) { + result = Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(updateGroupNameOnGraph.right().value())); + return result; + } + + result = Either.left(updateGroupNameOnGraph.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private Either updateGroupNameOnGraph(String uniqueId, String newName) { + + Either groupFromGraph = this.getGroupFromGraph(uniqueId, false, false, + false); + + if (groupFromGraph.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + return Either.right(status); + } else { + GroupDefinition groupDefinition = groupFromGraph.left().value(); + String version = groupDefinition.getVersion(); + String newVersion = increaseMajorVersion(version); + Integer pvCounter = groupDefinition.getPropertyValueCounter(); + + GroupData groupData = new GroupData(); + groupData.getGroupDataDefinition().setUniqueId(uniqueId); + groupData.getGroupDataDefinition().setVersion(newVersion); + groupData.getGroupDataDefinition().setName(newName); + groupData.getGroupDataDefinition().setPropertyValueCounter(pvCounter); + + Either updateNode = titanGenericDao.updateNode(groupData, GroupData.class); + if (updateNode.isRight()) { + return Either.right(updateNode.right().value()); + } else { + groupFromGraph = this.getGroupFromGraph(uniqueId, false, false, false); + return groupFromGraph; + } + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java new file mode 100644 index 0000000000..4251e503e6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java @@ -0,0 +1,385 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +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.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.GroupTypeDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +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.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.CapabilityTypeData; +import org.openecomp.sdc.be.resources.data.GroupTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("group-type-operation") +public class GroupTypeOperation extends AbstractOperation implements IGroupTypeOperation { + + String CREATE_FLOW_CONTEXT = "CreateGroupType"; + String GET_FLOW_CONTEXT = "GetGroupType"; + + @Resource + private PropertyOperation propertyOperation; + + public GroupTypeOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(GroupTypeOperation.class.getName()); + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either addGroupType(GroupTypeDefinition groupTypeDefinition) { + + return addGroupType(groupTypeDefinition, false); + } + + @Override + public Either addGroupType(GroupTypeDefinition groupTypeDefinition, + boolean inTransaction) { + + Either result = null; + + try { + + Either eitherStatus = addGroupTypeToGraph(groupTypeDefinition); + + if (eitherStatus.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, + groupTypeDefinition.getType(), eitherStatus.right().value().name()); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + + } else { + GroupTypeData groupTypeData = eitherStatus.left().value(); + + String uniqueId = groupTypeData.getUniqueId(); + Either groupTypeRes = this.getGroupType(uniqueId, true); + + if (groupTypeRes.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, + groupTypeDefinition.getType(), eitherStatus.right().value().name()); + } + + result = groupTypeRes; + + } + + return result; + + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + + } + + public Either getGroupTypeByUid(String uniqueId) { + + Either result = null; + + Either groupTypesRes = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), uniqueId, GroupTypeData.class); + + if (groupTypesRes.isRight()) { + TitanOperationStatus status = groupTypesRes.right().value(); + log.debug("Group type {} cannot be found in graph. Status is {}", uniqueId, status); + return Either.right(status); + } + + GroupTypeData gtData = groupTypesRes.left().value(); + GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition(gtData.getGroupTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = propertyOperation.fillProperties(uniqueId, + properList -> groupTypeDefinition.setProperties(properList)); + + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of capability type {}", uniqueId); + return Either.right(propertiesStatus); + } + + result = Either.left(groupTypeDefinition); + + return result; + } + + @Override + public Either getGroupType(String uniqueId) { + + return getGroupType(uniqueId, false); + + } + + @Override + public Either getGroupType(String uniqueId, boolean inTransaction) { + Function> groupTypeGetter = uId -> getGroupTypeByUid( + uId); + return getElementType(groupTypeGetter, uniqueId, inTransaction); + + } + + @Override + public Either getLatestGroupTypeByType(String type) { + return getLatestGroupTypeByType(type, false); + } + + @Override + public Either getLatestGroupTypeByType(String type, + boolean inTransaction) { + Map mapCriteria = new HashMap<>(); + mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); + mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + return getGroupTypeByCriteria(type, mapCriteria, inTransaction); + + } + + public Either getGroupTypeByCriteria(String type, + Map properties, boolean inTransaction) { + Either result = null; + try { + if (type == null || type.isEmpty()) { + log.error("type is empty"); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + Either, TitanOperationStatus> groupTypeEither = titanGenericDao + .getByCriteria(NodeTypeEnum.GroupType, properties, GroupTypeData.class); + if (groupTypeEither.isRight()) { + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(groupTypeEither.right().value())); + } else { + GroupTypeDataDefinition dataDefinition = groupTypeEither.left().value().stream() + .map(e -> e.getGroupTypeDataDefinition()).findFirst().get(); + result = getGroupType(dataDefinition.getUniqueId(), inTransaction); + } + + return result; + + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + } + + @Override + public Either getGroupTypeByTypeAndVersion(String type, + String version) { + return getGroupTypeByTypeAndVersion(type, version, false); + } + + @Override + public Either getGroupTypeByTypeAndVersion(String type, String version, + boolean inTransaction) { + Map mapCriteria = new HashMap<>(); + mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); + mapCriteria.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + + return getGroupTypeByCriteria(type, mapCriteria, inTransaction); + } + + /** + * + * Add group type to graph. + * + * 1. Add group type node + * + * 2. Add edge between the former node to its parent(if exists) + * + * 3. Add property node and associate it to the node created at #1. (per + * property & if exists) + * + * @param groupTypeDefinition + * @return + */ + private Either addGroupTypeToGraph(GroupTypeDefinition groupTypeDefinition) { + + log.debug("Got group type {}", groupTypeDefinition); + + String ctUniqueId = UniqueIdBuilder.buildGroupTypeUid(groupTypeDefinition.getType(), + groupTypeDefinition.getVersion()); + // capabilityTypeDefinition.setUniqueId(ctUniqueId); + + GroupTypeData groupTypeData = buildGroupTypeData(groupTypeDefinition, ctUniqueId); + + log.debug("Before adding group type to graph. groupTypeData = {}", groupTypeData); + + Either createGTResult = titanGenericDao.createNode(groupTypeData, + GroupTypeData.class); + log.debug("After adding group type to graph. status is = {}", createGTResult); + + if (createGTResult.isRight()) { + TitanOperationStatus operationStatus = createGTResult.right().value(); + log.error("Failed to add group type {} to graph. Status is {}", groupTypeDefinition.getType(), operationStatus); + return Either.right(operationStatus); + } + + GroupTypeData resultCTD = createGTResult.left().value(); + List properties = groupTypeDefinition.getProperties(); + Either, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation + .addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.GroupType, properties); + if (addPropertiesToCapablityType.isRight()) { + log.error("Failed add properties {} to capability {}", properties, groupTypeDefinition.getType()); + return Either.right(addPropertiesToCapablityType.right().value()); + } + + String derivedFrom = groupTypeDefinition.getDerivedFrom(); + if (derivedFrom != null) { + + // TODO: Need to find the parent. need to take the latest one since + // we may have many versions of the same type + /* + * log.debug("Before creating relation between group type {} to its parent {}", ctUniqueId, derivedFrom); UniqueIdData from + * = new UniqueIdData(NodeTypeEnum.CapabilityType, ctUniqueId); + * UniqueIdData to = new UniqueIdData(NodeTypeEnum.CapabilityType, + * derivedFrom); Either + * createRelation = titanGenericDao .createRelation(from, to, + * GraphEdgeLabels.DERIVED_FROM, null); + * log.debug("After create relation between capability type {} to its parent {}. Status is {}", ctUniqueId, derivedFrom, if (createRelation.isRight()) { return + * Either.right(createRelation.right().value()); } + * + */ + } + + return Either.left(createGTResult.left().value()); + + } + + /** + * + * convert between graph Node object to Java object + * + * @param capabilityTypeData + * @return + */ + protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) { + log.debug("The object returned after create capability is {}", capabilityTypeData); + + CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition( + capabilityTypeData.getCapabilityTypeDataDefinition()); + + return capabilityTypeDefResult; + } + + private GroupTypeData buildGroupTypeData(GroupTypeDefinition groupTypeDefinition, String ctUniqueId) { + + GroupTypeData groupTypeData = new GroupTypeData(groupTypeDefinition); + + groupTypeData.getGroupTypeDataDefinition().setUniqueId(ctUniqueId); + Long creationDate = groupTypeData.getGroupTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + groupTypeData.getGroupTypeDataDefinition().setCreationTime(creationDate); + groupTypeData.getGroupTypeDataDefinition().setModificationTime(creationDate); + + return groupTypeData; + } + + public Either isCapabilityTypeDerivedFrom(String childCandidateType, + String parentCandidateType) { + Map propertiesToMatch = new HashMap(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childCandidateType); + Either, TitanOperationStatus> getResponse = titanGenericDao + .getByCriteria(NodeTypeEnum.CapabilityType, propertiesToMatch, CapabilityTypeData.class); + if (getResponse.isRight()) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch capability type {}, error: {}", childCandidateType, titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } + String childUniqueId = getResponse.left().value().get(0).getUniqueId(); + Set travelledTypes = new HashSet<>(); + do { + travelledTypes.add(childUniqueId); + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childUniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch derived from node for capability type {}, error: {}", childCandidateType, + titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } else { + log.debug("Derived from node is not found for type {} - this is OK for root capability."); + return Either.left(false); + } + } + String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId(); + if (derivedFromUniqueId.equals(parentCandidateType)) { + log.debug("Verified that capability type {} derives from capability type {}", childCandidateType, + parentCandidateType); + return Either.left(true); + } + childUniqueId = derivedFromUniqueId; + } while (!travelledTypes.contains(childUniqueId)); + // this stop condition should never be used, if we use it, we have an + // illegal cycle in graph - "derived from" hierarchy cannot be cycled. + // It's here just to avoid infinite loop in case we have such cycle. + log.error("Detected a cycle of \"derived from\" edges starting at capability type node {}", childUniqueId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + /** + * FOR TEST ONLY + * + * @param propertyOperation + */ + public void setPropertyOperation(PropertyOperation propertyOperation) { + this.propertyOperation = propertyOperation; + } + + @Override + public Either getLatestGroupTypeByNameFromGraph(String name) { + + return null; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java new file mode 100644 index 0000000000..5d7b8c5991 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java @@ -0,0 +1,492 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.thinkaurelius.titan.core.TitanTransaction; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +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.HeatParameterDefinition; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.heat.HeatParameterType; +import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; +import org.openecomp.sdc.be.resources.data.HeatParameterData; +import org.openecomp.sdc.be.resources.data.HeatParameterValueData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; + +import fj.data.Either; + +@Component("heat-parameter-operation") +public class HeatParametersOperation implements IHeatParametersOperation { + + public static final String EMPTY_VALUE = null; + + private static Logger log = LoggerFactory.getLogger(HeatParametersOperation.class.getName()); + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + private Gson gson = new Gson(); + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List properties) { + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.HEAT_PARAMETER, NodeTypeEnum.HeatParameter, + HeatParameterData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + + List> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + if (log.isDebugEnabled()) + log.debug("Property {} is associated to node {}", propertyName, uniqueId); + HeatParameterData propertyData = immutablePair.getKey(); + HeatParameterDefinition propertyDefinition = convertParameterDataToParameterDefinition(propertyData, propertyName, uniqueId); + + properties.add(propertyDefinition); + + if (log.isTraceEnabled()) { + log.trace("getHeatParametersOfNode - property {} associated to node {}", propertyDefinition, uniqueId); + } + } + + } + + return StorageOperationStatus.OK; + } + + public StorageOperationStatus getParametersValueNodes(NodeTypeEnum parentNodeType, String parentUniqueId, List heatValues) { + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentUniqueId, GraphEdgeLabels.PARAMETER_VALUE, + NodeTypeEnum.HeatParameterValue, HeatParameterValueData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + + List> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + log.trace("Heat value " + propertyName + " is associated to node " + parentUniqueId); + HeatParameterValueData propertyData = immutablePair.getKey(); + + heatValues.add(propertyData); + } + + } + + return StorageOperationStatus.OK; + } + + @Override + public Either, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) { + + List heatParams = new ArrayList(); + StorageOperationStatus propertiesOfNodeRes = getHeatParametersOfNode(nodeType, uniqueId, heatParams); + + if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) { + return Either.right(propertiesOfNodeRes); + } + + for (HeatParameterDefinition propertyDefinition : heatParams) { + + String propertyUid = propertyDefinition.getUniqueId(); + Either deletePropertyRes = deleteHeatParameterFromGraph(propertyUid); + if (deletePropertyRes.isRight()) { + log.error("Failed to delete heat parameter with id {}", propertyUid); + TitanOperationStatus status = deletePropertyRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } + + log.debug("The heat parameters deleted from node {} are {}", uniqueId, heatParams); + return Either.left(heatParams); + } + + @Override + public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId) { + + List heatValues = new ArrayList(); + StorageOperationStatus propertiesOfNodeRes = getParametersValueNodes(parentNodeType, parentUniqueId, heatValues); + + if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) { + return propertiesOfNodeRes; + } + + for (HeatParameterValueData propertyDefinition : heatValues) { + + String propertyUid = (String) propertyDefinition.getUniqueId(); + Either deletePropertyRes = deleteHeatParameterValueFromGraph(propertyUid); + if (deletePropertyRes.isRight()) { + log.error("Failed to delete heat parameter value with id {}", propertyUid); + TitanOperationStatus status = deletePropertyRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + + } + + log.debug("The heat values deleted from node {} are {}", parentUniqueId, heatValues); + return StorageOperationStatus.OK; + } + + private Either deleteHeatParameterFromGraph(String propertyId) { + log.debug("Before deleting heat parameter from graph {}", propertyId); + return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameter), propertyId, HeatParameterData.class); + } + + private Either deleteHeatParameterValueFromGraph(String propertyId) { + log.debug("Before deleting heat parameter from graph {}", propertyId); + return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameterValue), propertyId, HeatParameterValueData.class); + } + + @Override + public StorageOperationStatus addPropertiesToGraph(List properties, String parentId, NodeTypeEnum nodeType) { + + if (properties != null) { + for (HeatParameterDefinition propertyDefinition : properties) { + + String propertyName = propertyDefinition.getName(); + + // type and value should be validated in business logic: + // ArtifactsBusinessLogic.validateAndConvertHeatParamers(ArtifactDefinition) + + // StorageOperationStatus validateAndUpdateProperty = + // validateAndUpdateProperty(propertyDefinition); + // if (validateAndUpdateProperty != StorageOperationStatus.OK) { + // log.error("Property " + propertyDefinition + " is invalid. + // Status is " + validateAndUpdateProperty); + // return StorageOperationStatus.BAD_REQUEST; + // } + + Either addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, parentId, nodeType); + + if (addPropertyToGraph.isRight()) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToGraph.right().value()); + } + } + } + + return StorageOperationStatus.OK; + + } + + @Override + public StorageOperationStatus updateHeatParameters(List properties) { + + if (properties == null) { + return StorageOperationStatus.OK; + } + for (HeatParameterDefinition property : properties) { + + HeatParameterData heatParameterData = new HeatParameterData(property); + Either updateNode = titanGenericDao.updateNode(heatParameterData, HeatParameterData.class); + if (updateNode.isRight()) { + log.debug("failed to update heat parameter in graph. id = {}", property.getUniqueId()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()); + } + } + + return StorageOperationStatus.OK; + } + + public Either addPropertyToGraph(String propertyName, HeatParameterDefinition propertyDefinition, String parentId, NodeTypeEnum nodeType) { + + UniqueIdData parentNode = new UniqueIdData(nodeType, parentId); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildHeatParameterUniqueId(parentId, propertyName)); + HeatParameterData propertyData = new HeatParameterData(propertyDefinition); + + log.debug("Before adding property to graph {}", propertyData); + Either createNodeResult = titanGenericDao.createNode(propertyData, HeatParameterData.class); + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. Status is {}", propertyName, operationStatus); + return Either.right(operationStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + Either createRelResult = titanGenericDao.createRelation(parentNode, propertyData, GraphEdgeLabels.HEAT_PARAMETER, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + + if (log.isDebugEnabled()) { + log.error("Failed to associate {} {} to heat parameter {} in graph. Status is {}", nodeType.getName(), parentId, propertyName, operationStatus); + } + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition propertyDefinition) { + + log.trace("Going to validate property type and value. {}", propertyDefinition); + + String propertyType = propertyDefinition.getType(); + HeatParameterType type = getType(propertyType); + + if (type == null) { + log.info("The type {} of heat is invalid", type); + + return StorageOperationStatus.INVALID_TYPE; + } + propertyDefinition.setType(type.getType()); + + log.trace("After validating property type {}", propertyType); + + // validate default value + String defaultValue = propertyDefinition.getDefaultValue(); + boolean isValidProperty = isValidValue(type, defaultValue); + if (false == isValidProperty) { + log.info("The value {} of property from type {} is invalid", defaultValue, type); + return StorageOperationStatus.INVALID_VALUE; + } + + PropertyValueConverter converter = type.getConverter(); + + if (isEmptyValue(defaultValue)) { + log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE); + propertyDefinition.setDefaultValue(EMPTY_VALUE); + } else if (false == isEmptyValue(defaultValue)) { + String convertedValue = converter.convert(defaultValue, null, null); + propertyDefinition.setDefaultValue(convertedValue); + } + + // validate current value + String value = propertyDefinition.getCurrentValue(); + isValidProperty = isValidValue(type, value); + if (false == isValidProperty) { + log.info("The value {} of property from type {} is invalid", value, type); + return StorageOperationStatus.INVALID_VALUE; + } + + if (isEmptyValue(value)) { + log.debug("Value was not sent for property {}. Set value to {}", propertyDefinition.getName(), EMPTY_VALUE); + propertyDefinition.setCurrentValue(EMPTY_VALUE); + } else if (!value.equals("")) { + String convertedValue = converter.convert(value, null, null); + propertyDefinition.setCurrentValue(convertedValue); + } + + return StorageOperationStatus.OK; + } + + public HeatParameterDefinition convertParameterDataToParameterDefinition(HeatParameterData propertyDataResult, String propertyName, String resourceId) { + log.debug("convert to HeatParamereDefinition {}", propertyDataResult); + + HeatParameterDefinition propertyDefResult = new HeatParameterDefinition(propertyDataResult.getHeatDataDefinition()); + + propertyDefResult.setName(propertyName); + + return propertyDefResult; + } + + private HeatParameterType getType(String propertyType) { + + HeatParameterType type = HeatParameterType.isValidType(propertyType); + + return type; + + } + + protected boolean isValidValue(HeatParameterType type, String value) { + if (isEmptyValue(value)) { + return true; + } + + PropertyTypeValidator validator = type.getValidator(); + + boolean isValid = validator.isValid(value, null, null); + if (true == isValid) { + return true; + } else { + return false; + } + + } + + public boolean isEmptyValue(String value) { + if (value == null) { + return true; + } + return false; + } + + public boolean isNullParam(String value) { + if (value == null) { + return true; + } + return false; + } + + @Override + public Either updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) { + String heatEnvId = UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParam.getName()); + Either getNode = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatEnvId, HeatParameterValueData.class); + if (getNode.isRight() || getNode.left().value() == null) { + if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) { + log.debug("Updated heat parameter value equals default value. No need to create heat parameter value for heat parameter {}", heatParam.getUniqueId()); + return Either.left(null); + } + return createHeatParameterValue(heatParam, artifactId, resourceInstanceId, artifactLabel); + } else { + heatParam.setUniqueId(heatEnvId); + return updateHeatParameterValue(heatParam); + } + } + + public Either updateHeatParameterValue(HeatParameterDefinition heatParam) { + HeatParameterValueData heatParameterValue = new HeatParameterValueData(); + heatParameterValue.setUniqueId(heatParam.getUniqueId()); + if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) { + Either deleteParameterValueIncomingRelation = titanGenericDao.deleteIncomingRelationByCriteria(heatParameterValue, GraphEdgeLabels.PARAMETER_VALUE, null); + if (deleteParameterValueIncomingRelation.isRight()) { + log.debug("Failed to delete heat parameter value incoming relation on graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteParameterValueIncomingRelation.right().value())); + } + Either getOutgoingRelation = titanGenericDao.getOutgoingEdgeByCriteria(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) heatParameterValue.getUniqueId(), GraphEdgeLabels.PARAMETER_IMPL, null); + if (getOutgoingRelation.isRight()) { + log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getOutgoingRelation.right().value())); + } + Edge edge = getOutgoingRelation.left().value(); + if (edge == null) { + log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + edge.remove(); + + Either deleteNode = titanGenericDao.deleteNode(heatParameterValue, HeatParameterValueData.class); + if (deleteNode.isRight()) { + log.debug("Failed to delete heat parameter value on graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value())); + } + return Either.left(deleteNode.left().value()); + } + heatParameterValue.setValue(heatParam.getCurrentValue()); + Either updateNode = titanGenericDao.updateNode(heatParameterValue, HeatParameterValueData.class); + if (updateNode.isRight()) { + log.debug("Failed to update heat parameter value in graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + } + return Either.left(updateNode.left().value()); + } + + public Either createHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) { + + Either addHeatValueToGraph = addHeatValueToGraph(heatParam, artifactLabel, artifactId, resourceInstanceId); + if (addHeatValueToGraph.isRight()) { + log.debug("Failed to create heat parameters value on graph for artifact {}", artifactId); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addHeatValueToGraph.right().value())); + } + return Either.left(addHeatValueToGraph.left().value()); + } + + public Either addHeatValueToGraph(HeatParameterDefinition heatParameter, String artifactLabel, String artifactId, String resourceInstanceId) { + + UniqueIdData heatEnvNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId); + HeatParameterValueData heatValueData = new HeatParameterValueData(); + heatValueData.setUniqueId(UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParameter.getName())); + heatValueData.setValue(heatParameter.getCurrentValue()); + + log.debug("Before adding property to graph {}", heatValueData); + Either createNodeResult = titanGenericDao.createNode(heatValueData, HeatParameterValueData.class); + log.debug("After adding property to graph {}", heatValueData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add heat value {} to graph. Status is {}", heatValueData.getUniqueId(), operationStatus); + return Either.right(operationStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), heatParameter.getName()); + Either createRelResult = titanGenericDao.createRelation(heatEnvNode, heatValueData, GraphEdgeLabels.PARAMETER_VALUE, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate heat value {} to heat env artifact {} in graph. Status is {}", heatValueData.getUniqueId(), artifactId, operationStatus); + return Either.right(operationStatus); + } + UniqueIdData heatParameterNode = new UniqueIdData(NodeTypeEnum.HeatParameter, heatParameter.getUniqueId()); + Either createRel2Result = titanGenericDao.createRelation(heatValueData, heatParameterNode, GraphEdgeLabels.PARAMETER_IMPL, null); + if (createRel2Result.isRight()) { + TitanOperationStatus operationStatus = createRel2Result.right().value(); + log.error("Failed to associate heat value {} to heat parameter {} in graph. Status is {}", heatValueData.getUniqueId(), heatParameter.getName(), operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java new file mode 100644 index 0000000000..e2d13a9cff --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java @@ -0,0 +1,1184 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.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 java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.json.simple.JSONObject; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +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.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +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.DataTypeDefinition; +import org.openecomp.sdc.be.model.GetInputValueInfo; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.operations.api.IInputsOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.InputValueData; +import org.openecomp.sdc.be.resources.data.InputsData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; +import com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; +import com.thinkaurelius.titan.core.TitanVertexQuery; +import com.thinkaurelius.titan.core.attribute.Cmp; + +import fj.data.Either; + +@Component("input-operation") +public class InputsOperation extends AbstractOperation implements IInputsOperation { + + private static String ASSOCIATING_INPUT_TO_PROP = "AssociatingInputToComponentInstanceProperty"; + + private static Logger log = LoggerFactory.getLogger(InputsOperation.class.getName()); + + @Autowired + private ComponentInstanceOperation componentInstanceOperation; + Gson gson = new Gson(); + + /** + * Delete specific input from component Although inputId is unique, pass also componentId as all other methods, and also check that the inputId is inside that componentId. + */ + @Override + public Either deleteInput(String inputId) { + log.debug(String.format("Before deleting input: %s from graph", inputId)); + Either, TitanOperationStatus> inputsValueStatus = this.getComponentInstanceInputsByInputId(inputId); + if(inputsValueStatus.isLeft()){ + List inputsValueLis = inputsValueStatus.left().value(); + if(!inputsValueLis.isEmpty()){ + for(ComponentInstanceInput inputValue: inputsValueLis){ + Either deleteNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), inputValue.getValueUniqueUid(), InputValueData.class); + if (deleteNode.isRight()) { + StorageOperationStatus convertTitanStatusToStorageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value()); + return Either.right(convertTitanStatusToStorageStatus); + } + } + } + } + Either deleteNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), inputId, InputsData.class); + if (deleteNode.isRight()) { + StorageOperationStatus convertTitanStatusToStorageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value()); + return Either.right(convertTitanStatusToStorageStatus); + } else { + return Either.left(inputId); + } + } + + @Override + public Either, TitanOperationStatus> addInputsToGraph(String componentId, NodeTypeEnum nodeType, Map inputs, Map dataTypes) { + + List newInputs = new ArrayList(); + if (inputs != null) { + for (Entry entry : inputs.entrySet()) { + + String inputName = entry.getKey(); + InputDefinition propertyDefinition = entry.getValue(); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property " + propertyDefinition + " is invalid. Status is " + validateAndUpdateProperty); + return Either.right(TitanOperationStatus.INVALID_PROPERTY); + } + + Either addPropertyToGraph = addInputToGraph(inputName, propertyDefinition, componentId, nodeType); + + if (addPropertyToGraph.isRight()) { + return Either.right(addPropertyToGraph.right().value()); + } + InputDefinition createdInputyDefinition = convertInputDataToInputDefinition(addPropertyToGraph.left().value()); + createdInputyDefinition.setName(inputName); + createdInputyDefinition.setParentUniqueId(componentId); + newInputs.add(createdInputyDefinition); + } + } + + return Either.left(newInputs); + } + + @Override + public TitanOperationStatus addInputsToGraph(TitanVertex metadata, String componentId, Map inputs, Map dataTypes) { + + if (inputs != null) { + for (Entry entry : inputs.entrySet()) { + + String inputName = entry.getKey(); + InputDefinition propertyDefinition = entry.getValue(); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property {} is invalid. Status is {} ", propertyDefinition, validateAndUpdateProperty); + return TitanOperationStatus.INVALID_PROPERTY; + } + + TitanOperationStatus addPropertyToGraph = addInputToGraph(metadata, inputName, propertyDefinition, componentId); + + if (!addPropertyToGraph.equals(TitanOperationStatus.OK)) { + return addPropertyToGraph; + } + + } + } + + return TitanOperationStatus.OK; + } + + @Override + public Either, StorageOperationStatus> getInputsOfComponent(String compId, String fromName, int amount) { + List inputs = new ArrayList<>(); + if ((fromName == null || fromName.isEmpty()) && amount == 0) { + + TitanOperationStatus status = findAllResourceInputs(compId, inputs); + + if (status != TitanOperationStatus.OK) { + log.error("Failed to set inputs of resource {}. status is {}", compId, status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } else { + + Either graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.error("Failed to retrieve graph. status is {}", graphRes); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphRes.right().value())); + } + + TitanGraph titanGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = titanGraph.query().has(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), compId).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.INVALID_ID)); + } + + TitanVertex rootVertex = vertices.iterator().next(); + TitanVertexQuery query; + if (fromName == null || fromName.isEmpty()) + query = rootVertex.query().direction(Direction.OUT).labels(GraphEdgeLabels.INPUT.getProperty()).orderBy(GraphEdgePropertiesDictionary.NAME.getProperty(), Order.incr).limit(amount); + else + query = rootVertex.query().direction(Direction.OUT).labels(GraphEdgeLabels.INPUT.getProperty()).orderBy(GraphEdgePropertiesDictionary.NAME.getProperty(), Order.incr).has(GraphEdgePropertiesDictionary.NAME.getProperty(), Cmp.GREATER_THAN, fromName).limit(amount); + + Iterable edgesCreatorEges = query.edges(); + + if (edgesCreatorEges == null) { + log.debug("No edges in graph for criteria"); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.NOT_FOUND)); + } + Iterator edgesCreatorIterator = edgesCreatorEges.iterator(); + + if (edgesCreatorIterator != null) { + while (edgesCreatorIterator.hasNext()) { + Edge edge = edgesCreatorIterator.next(); + GraphEdge graphEdge = null; + + Map edgeProps = titanGenericDao.getProperties(edge); + GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); + graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); + + Vertex outgoingVertex = edge.inVertex(); + Map properties = titanGenericDao.getProperties(outgoingVertex); + InputsData data = GraphElementFactory.createElement(NodeTypeEnum.Input.getName(), GraphElementTypeEnum.Node, properties, InputsData.class); + String inputName = (String) graphEdge.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + InputDefinition inputDefinition = this.convertInputDataToInputDefinition(data); + inputDefinition.setName(inputName); + inputDefinition.setParentUniqueId(compId); + + inputs.add(inputDefinition); + + } + } + + } + if (true == inputs.isEmpty()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.NOT_FOUND)); + } + + return Either.left(inputs); + + } + + @Override + public Either, StorageOperationStatus> deleteAllInputsAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) { + + Wrapper errorWrapper; + List inputs = new ArrayList<>(); + TitanOperationStatus findAllResourceAttribues = this.findNodeNonInheretedInputs(uniqueId, inputs); + errorWrapper = (findAllResourceAttribues != TitanOperationStatus.OK) ? new Wrapper<>(findAllResourceAttribues) : new Wrapper<>(); + + if (errorWrapper.isEmpty()) { + for (InputDefinition inDef : inputs) { + log.debug("Before deleting inputs from graph {}", inDef.getUniqueId()); + Either deleteNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), inDef.getUniqueId(), InputsData.class); + if (deleteNode.isRight()) { + errorWrapper.setInnerElement(deleteNode.right().value()); + break; + } + } + } + + if (errorWrapper.isEmpty()) { + Map inputsMap = inputs.stream().collect(Collectors.toMap(e -> e.getName(), e -> e)); + return Either.left(inputsMap); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(errorWrapper.getInnerElement())); + } + + } + + @Override + public Either addInput(String inputName, InputDefinition inputDefinition, String resourceId, NodeTypeEnum nodeType) { + + ComponentMetadataData componentMetadata = null; + + Either either = addInputToGraph(inputName, inputDefinition, resourceId, nodeType); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + @Override + public Either updateInput(String inputId, InputDefinition newInDef, Map dataTypes) { + // TODO Auto-generated method stub + return null; + } + + public Either addInputToGraph(String propertyName, InputDefinition inputDefinition, String componentId, NodeTypeEnum nodeType) { + + UniqueIdData from = new UniqueIdData(nodeType, componentId); + + List constraints = inputDefinition.getConstraints(); + + inputDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, propertyName)); + InputsData inputData = new InputsData(inputDefinition, convertConstraintsToString(constraints)); + + log.debug("Before adding property to graph {}", inputData); + Either createNodeResult = titanGenericDao.createNode(inputData, InputsData.class); + log.debug("After adding input to graph {}", inputData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add input {} to graph. status is {}", propertyName, operationStatus); + return Either.right(operationStatus); + } + + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), propertyName); + + Either createRelResult = titanGenericDao.createRelation(from, inputData, GraphEdgeLabels.INPUT, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate resource {} to property {} in graph. status is {}", componentId, propertyName, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + public TitanOperationStatus addInputToGraph(TitanVertex vertex, String propertyName, InputDefinition inputDefinition, String componentId) { + + List constraints = inputDefinition.getConstraints(); + + inputDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, propertyName)); + InputsData inputData = new InputsData(inputDefinition, convertConstraintsToString(constraints)); + + log.debug("Before adding property to graph {}", inputData); + Either createNodeResult = titanGenericDao.createNode(inputData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add input {} to graph. status is {}", propertyName, operationStatus); + return operationStatus; + } + + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), propertyName); + TitanVertex inputVertex = createNodeResult.left().value(); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(vertex, inputVertex, GraphEdgeLabels.INPUT, props); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + TitanOperationStatus operationStatus = createRelResult; + log.error("Failed to associate resource {} to property {} in graph. status is {}", componentId, propertyName, operationStatus); + return operationStatus; + } + + return createRelResult; + + } + + public InputDefinition convertInputDataToInputDefinition(InputsData inputDataResult) { + if (log.isDebugEnabled()) + log.debug("The object returned after create property is {}", inputDataResult); + + InputDefinition propertyDefResult = new InputDefinition(inputDataResult.getPropertyDataDefinition()); + propertyDefResult.setConstraints(convertConstraints(inputDataResult.getConstraints())); + + return propertyDefResult; + } + + public boolean isInputExist(List inputs, String resourceUid, String inputName) { + + if (inputs == null) { + return false; + } + + for (InputDefinition propertyDefinition : inputs) { + String parentUniqueId = propertyDefinition.getParentUniqueId(); + String name = propertyDefinition.getName(); + + if (parentUniqueId.equals(resourceUid) && name.equals(inputName)) { + return true; + } + } + + return false; + + } + + @Override + public TitanOperationStatus findAllResourceInputs(String uniqueId, List inputs) { + // final NodeElementFetcher singleNodeFetcher = + // (resourceIdParam, attributesParam) -> + // findNodeNonInheretedInputs(resourceIdParam, componentType, + // attributesParam); + // return findAllResourceElementsDefinitionRecursively(uniqueId, inputs, + // singleNodeFetcher); + return findNodeNonInheretedInputs(uniqueId, inputs); + } + + @Override + public TitanOperationStatus findNodeNonInheretedInputs(String uniqueId, List inputs) { + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.INPUT, NodeTypeEnum.Input, InputsData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return status; + } + + List> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String inputName = (String) edge.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + log.debug("Input {} is associated to node {}", inputName, uniqueId); + InputsData inputData = immutablePair.getKey(); + InputDefinition inputDefinition = this.convertInputDataToInputDefinition(inputData); + + inputDefinition.setName(inputName); + inputDefinition.setParentUniqueId(uniqueId); + + inputs.add(inputDefinition); + + log.trace("findInputsOfNode - input {} associated to node {}", inputDefinition, uniqueId); + } + + } + + return TitanOperationStatus.OK; + } + + public Either getInputById(String uniqueId, boolean skipProperties, boolean skipInputsvalue) { + Either status = getInputFromGraph(uniqueId, skipProperties, skipInputsvalue); + + if (status.isRight()) { + log.error("Failed to get input {} from graph {}. status is {}", uniqueId, status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } + + return Either.left(status.left().value()); + + } + + public TitanOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId, List elements, NodeElementFetcher singleNodeFetcher) { + + log.trace("Going to fetch elements under resource {}", resourceId); + TitanOperationStatus resourceAttributesStatus = singleNodeFetcher.findAllNodeElements(resourceId, elements); + + if (resourceAttributesStatus != TitanOperationStatus.OK) { + return resourceAttributesStatus; + } + + Either, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (parentNodesStatus != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find parent elements of resource " + resourceId + ". status is " + parentNodesStatus, ErrorSeverity.ERROR); + return parentNodesStatus; + } + } + + if (parentNodes.isLeft()) { + ImmutablePair parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findAllResourceElementsDefinitionRecursively(parentUniqueId, elements, singleNodeFetcher); + + if (addParentIntStatus != TitanOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find all resource elements of resource " + parentUniqueId, ErrorSeverity.ERROR); + + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + } + + public TitanOperationStatus associatePropertyToInput(String riId, String inputId, InputValueData property, String name) { + TitanOperationStatus status = TitanOperationStatus.OK; + Either graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.error("Failed to retrieve graph. status is {}", graphRes); + return graphRes.right().value(); + } + + TitanGraph titanGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = titanGraph.query().has(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), property.getUniqueId()).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return TitanOperationStatus.INVALID_ID; + } + // Either findPropertyDefRes = + // titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), + // propertyId, PropertyData.class); + + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), name); + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), riId); + + GraphNode inputData = new UniqueIdData(NodeTypeEnum.Input, inputId); + GraphNode propertyData = new UniqueIdData(NodeTypeEnum.InputValue, property.getUniqueId()); + Either addPropRefResult = titanGenericDao.createRelation(inputData, propertyData, GraphEdgeLabels.GET_INPUT, props); + + if (addPropRefResult.isRight()) { + status = addPropRefResult.right().value(); + String description = "Failed to associate input " + inputData.getUniqueId() + " to property " + property.getUniqueId() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ASSOCIATING_INPUT_TO_PROP, description, ErrorSeverity.ERROR); + return status; + } + return status; + + } + + public TitanOperationStatus associatePropertyToInput(String riId, String inputId, ComponentInstanceProperty property, GetInputValueInfo getInput) { + TitanOperationStatus status = TitanOperationStatus.OK; + Either graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.error("Failed to retrieve graph. status is {}", graphRes); + return graphRes.right().value(); + } + + TitanGraph titanGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable vertices = titanGraph.query().has(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), property.getUniqueId()).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return TitanOperationStatus.INVALID_ID; + } + // Either findPropertyDefRes = + // titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), + // propertyId, PropertyData.class); + + Map props = new HashMap(); + if(getInput!=null){ + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), getInput.getPropName()); + if (getInput.isList()) { + String index = getInput.getIndexValue().toString(); + if (getInput.getGetInputIndex() != null) { + index = getInput.getGetInputIndex().getInputName(); + + } + props.put(GraphEdgePropertiesDictionary.GET_INPUT_INDEX.getProperty(), index); + } + } + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), riId); + + GraphNode inputData = new UniqueIdData(NodeTypeEnum.Input, inputId); + GraphNode propertyData = new UniqueIdData(NodeTypeEnum.PropertyValue, property.getValueUniqueUid()); + Either addPropRefResult = titanGenericDao.createRelation(inputData, propertyData, GraphEdgeLabels.GET_INPUT, props); + + if (addPropRefResult.isRight()) { + status = addPropRefResult.right().value(); + String description = "Failed to associate input " + inputData.getUniqueId() + " to property " + property.getUniqueId() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ASSOCIATING_INPUT_TO_PROP, description, ErrorSeverity.ERROR); + return status; + } + return status; + + } + + private Either getInputFromGraph(String uniqueId, boolean skipProperties, boolean skipInputsValue) { + + Either result = null; + + Either inputRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), uniqueId, InputsData.class); + if (inputRes.isRight()) { + TitanOperationStatus status = inputRes.right().value(); + log.debug("Failed to retrieve group {} from graph. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Group", uniqueId, String.valueOf(status)); + result = Either.right(status); + return result; + } + + InputsData inputData = inputRes.left().value(); + + InputDefinition groupDefinition = this.convertInputDataToInputDefinition(inputData); + + if (false == skipInputsValue) { + List propsList = new ArrayList(); + + Either>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), uniqueId, GraphEdgeLabels.GET_INPUT, NodeTypeEnum.InputValue, InputValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + return Either.right(status); + } + + } + if(propertyImplNodes.isLeft()){ + List> propertyDataPairList = propertyImplNodes.left().value(); + for (ImmutablePair propertyValue : propertyDataPairList) { + + InputValueData propertyValueData = propertyValue.getLeft(); + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), propertyValueUid, GraphEdgeLabels.INPUT_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair propertyDefPair = propertyDefRes.left().value(); + String propertyUniqueId = (String) propertyDefPair.left.getUniqueId(); + + ComponentInstanceInput resourceInstanceProperty = new ComponentInstanceInput(); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueUid); + // set rules + // resourceInstanceProperty.setRules(propertyValueData.getRules()); + + propsList.add(resourceInstanceProperty); + + } + + groupDefinition.setInputsValue(propsList); + } + + } + + if (false == skipProperties) { + Either>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.GET_INPUT, NodeTypeEnum.PropertyValue, PropertyValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List> list = propertyImplNodes.left().value(); + + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List propsRresult = new ArrayList<>(); + for (ImmutablePair propertyValueDataPair : list) { + PropertyValueData propertyValueData = propertyValueDataPair.left; + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + return Either.right(status); + } + + } + if(propertyDefRes.isLeft()){ + + ImmutablePair propertyDefPair = propertyDefRes.left().value(); + PropertyData propertyData = propertyDefPair.left; + String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId(); + + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId()); + // set rules + resourceInstanceProperty.setRules(propertyValueData.getRules()); + resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType()); + resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema()); + resourceInstanceProperty.setName((String) propertyValueDataPair.right.getProperties().get(GraphPropertiesDictionary.NAME.getProperty())); + + propsRresult.add(resourceInstanceProperty); + } + + groupDefinition.setProperties(propsRresult); + } + + } + + result = Either.left(groupDefinition); + + return result; + + } + + public ImmutablePair findInputValue(String resourceInstanceId, String propertyId) { + + log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId); + + Either, TitanOperationStatus> getAllRes = getAllInputsOfResourceInstanceOnlyInputDefId(resourceInstanceId); + if (getAllRes.isRight()) { + TitanOperationStatus status = getAllRes.right().value(); + log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status); + return new ImmutablePair(status, null); + } + + List list = getAllRes.left().value(); + if (list != null) { + for (ComponentInstanceInput instanceProperty : list) { + String propertyUniqueId = instanceProperty.getUniqueId(); + String valueUniqueUid = instanceProperty.getValueUniqueUid(); + log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid); + if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) { + log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId); + return new ImmutablePair(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid); + } + } + } + + return new ImmutablePair(TitanOperationStatus.NOT_FOUND, null); + } + + /** + * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value... + * + * @param resourceInstanceUid + * @return + */ + public Either, TitanOperationStatus> getAllInputsOfResourceInstanceOnlyInputDefId(String resourceInstanceUid) { + + return getAllInputsOfResourceInstanceOnlyInputDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance); + + } + + /** + * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value... + * + * @param resourceInstanceUid + * @return + */ + public Either, StorageOperationStatus> getComponentInstanceInputsByInputId(String resourceInstanceUid, String inputId) { + + Either, TitanOperationStatus> status = getComponentInstanceInputsByInputId(inputId); + if (status.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } + + return Either.left(status.left().value()); + + } + + /** + * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value... + * + * @param resourceInstanceUid + * @return + */ + public Either, StorageOperationStatus> getComponentInstancePropertiesByInputId(String resourceInstanceUid, String inputId) { + + Either, TitanOperationStatus> status = getComponentInstancePropertiesByInputId(inputId); + if (status.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } + + return Either.left(status.left().value()); + + } + + public Either, TitanOperationStatus> getAllInputsOfResourceInstanceOnlyInputDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) { + + Either findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, ComponentInstanceData.class); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + Either>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.INPUT_VALUE, NodeTypeEnum.InputValue, InputValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List> list = propertyImplNodes.left().value(); + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List result = new ArrayList<>(); + + + for (ImmutablePair propertyValueDataPair : list) { + + InputValueData propertyValueData = propertyValueDataPair.getLeft(); + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either, TitanOperationStatus> inputNodes = titanGenericDao.getParentNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), propertyValueData.getUniqueId(), GraphEdgeLabels.GET_INPUT, NodeTypeEnum.Input, InputsData.class); + + if (inputNodes.isRight()) { + + return Either.right(inputNodes.right().value()); + } + + InputsData input = inputNodes.left().value().left; + String inputId = input.getPropertyDataDefinition().getUniqueId(); + + Either, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), propertyValueUid, GraphEdgeLabels.INPUT_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair propertyDefPair = propertyDefRes.left().value(); + PropertyData propertyData = propertyDefPair.left; + Either inputsEges = titanGenericDao.getIncomingEdgeByCriteria(propertyData, GraphEdgeLabels.INPUT, null); + if (inputsEges.isRight()) { + TitanOperationStatus status = inputsEges.right().value(); + + return Either.right(status); + } + Edge edge = inputsEges.left().value(); + String inputName = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.NAME.getProperty()); + + String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId(); + + + ComponentInstanceInput resourceInstanceProperty = new ComponentInstanceInput(propertyData.getPropertyDataDefinition(), inputId, value, propertyValueUid); + + //resourceInstanceProperty.setName(inputName); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setName(inputName); + resourceInstanceProperty.setParentUniqueId(inputId); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId()); + // set rules + // resourceInstanceProperty.setRules(propertyValueData.getRules()); + resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType()); + resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema()); + //resourceInstanceProperty.setComponentInstanceName(componentInsName); + resourceInstanceProperty.setComponentInstanceId(resourceInstanceUid); + + result.add(resourceInstanceProperty); + } + + + return Either.left(result); + } + + public Either, TitanOperationStatus> getComponentInstanceInputsByInputId(String inputId) { + + Either findResInputRes = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId, InputsData.class); + + if (findResInputRes.isRight()) { + TitanOperationStatus status = findResInputRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + + + // Either, TitanOperationStatus> propertyImplNodes + // = titanGenericDao.getByCriteria(NodeTypeEnum.InputValue, props, + // InputValueData.class); + Either vertexService = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId); + + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of resource input for id = {}", inputId); + TitanOperationStatus status = vertexService.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + + return Either.right(status); + } + TitanVertex vertex = vertexService.left().value(); + + Either>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId, GraphEdgeLabels.GET_INPUT, NodeTypeEnum.InputValue, InputValueData.class); + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List> list = propertyImplNodes.left().value(); + + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List result = new ArrayList<>(); + for (ImmutablePair propertyValueDataPair : list) { + InputValueData propertyValueData = propertyValueDataPair.left; + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + // Either, TitanOperationStatus> out = + // titanGenericDao.getEdgesForNode(propertyValueData, + // Direction.OUT); + // Either, TitanOperationStatus> in = + // titanGenericDao.getEdgesForNode(propertyValueData, Direction.IN); + Either inputsvalueEges = titanGenericDao.getIncomingEdgeByCriteria(propertyValueData, GraphEdgeLabels.INPUT_VALUE, null); + if (inputsvalueEges.isRight()) { + TitanOperationStatus status = inputsvalueEges.right().value(); + + return Either.right(status); + } + Edge edge = inputsvalueEges.left().value(); + String componentInsName = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.NAME.getProperty()); + String componentInsId = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + + Either, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), propertyValueUid, GraphEdgeLabels.INPUT_IMPL, NodeTypeEnum.Input, InputsData.class); + + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair propertyDefPair = propertyDefRes.left().value(); + + InputsData propertyData = propertyDefPair.left; + + Either inputsEges = titanGenericDao.getIncomingEdgeByCriteria(propertyData, GraphEdgeLabels.INPUT, null); + if (inputsEges.isRight()) { + TitanOperationStatus status = inputsEges.right().value(); + + return Either.right(status); + } + edge = inputsEges.left().value(); + String inputName = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.NAME.getProperty()); + + String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId(); + + ComponentInstanceInput resourceInstanceProperty = new ComponentInstanceInput(propertyData.getPropertyDataDefinition(), inputId, value, propertyValueUid); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + resourceInstanceProperty.setName(inputName); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId()); + // set rules + // resourceInstanceProperty.setRules(propertyValueData.getRules()); + resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType()); + resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema()); + resourceInstanceProperty.setComponentInstanceName(componentInsName); + resourceInstanceProperty.setComponentInstanceId(componentInsId); + + result.add(resourceInstanceProperty); + } + + return Either.left(result); + + } + + public Either, TitanOperationStatus> getComponentInstancePropertiesByInputId(String inputId) { + + Either findResInputRes = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId, InputsData.class); + + if (findResInputRes.isRight()) { + TitanOperationStatus status = findResInputRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + //Map props = new HashMap(); + //props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), resourceInstanceUid); + + // Either, TitanOperationStatus> + // propertyImplNodes = + // titanGenericDao.getByCriteria(NodeTypeEnum.PropertyValue, props, + // PropertyValueData.class); + Either vertexService = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId); + + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of resource input for id = {}", inputId); + TitanOperationStatus status = vertexService.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + + return Either.right(status); + } + TitanVertex vertex = vertexService.left().value(); + + // Either>, + // TitanOperationStatus> propertyImplNodes = + // titanGenericDao.getChildrenByEdgeCriteria(vertex, inputId, + // GraphEdgeLabels.GET_INPUT, NodeTypeEnum.PropertyValue, + // PropertyValueData.class, props); + Either>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId, GraphEdgeLabels.GET_INPUT, NodeTypeEnum.PropertyValue, PropertyValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List> list = propertyImplNodes.left().value(); + + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List result = new ArrayList<>(); + for (ImmutablePair propertyValueDataPair : list) { + PropertyValueData propertyValueData = propertyValueDataPair.left; + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair propertyDefPair = propertyDefRes.left().value(); + PropertyData propertyData = propertyDefPair.left; + String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId(); + + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId()); + // set rules + resourceInstanceProperty.setRules(propertyValueData.getRules()); + resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType()); + resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema()); + resourceInstanceProperty.setName((String) propertyValueDataPair.right.getProperties().get(GraphPropertiesDictionary.NAME.getProperty())); + + result.add(resourceInstanceProperty); + } + + return Either.left(result); + } + + public ComponentInstanceInput buildResourceInstanceInput(InputValueData propertyValueData, ComponentInstanceInput resourceInstanceInput) { + + String value = propertyValueData.getValue(); + String uid = propertyValueData.getUniqueId(); + ComponentInstanceInput instanceProperty = new ComponentInstanceInput(resourceInstanceInput, value, uid); + instanceProperty.setPath(resourceInstanceInput.getPath()); + + return instanceProperty; + } + + public Either, TitanOperationStatus> getAllInputsOfResourceInstance(ComponentInstance compInstance) { + + Either, TitanOperationStatus> result; + + return getAllInputsOfResourceInstanceOnlyInputDefId(compInstance.getUniqueId()); + + } + + public Either, StorageOperationStatus> addInputsToComponent(String resourceId, NodeTypeEnum nodeType, ComponentInstInputsMap componentInsInputs, Map dataTypes) { + List resList = new ArrayList(); + Map> newInputsMap = componentInsInputs.getComponentInstanceInputsMap(); + if (newInputsMap != null && !newInputsMap.isEmpty()) { + for (Entry> entry : newInputsMap.entrySet()) { + String compInstId = entry.getKey(); + List inputs = entry.getValue(); + + if (inputs != null && !inputs.isEmpty()) { + for (InputDefinition input : inputs) { + + Either counterRes = componentInstanceOperation.increaseAndGetResourceInstanceSpecificCounter(compInstId, GraphPropertiesDictionary.INPUT_COUNTER, true); + if (counterRes.isRight()) { + log.debug("increaseAndGetResourceInputCounter failed resource instance {}", compInstId); + StorageOperationStatus status = counterRes.right().value(); + return Either.right(status); + } + + Either oldInputEither = getInputFromGraph(input.getUniqueId(), true, true); + if (oldInputEither.isRight()) { + log.error("Failed to get input {} ", input.getUniqueId()); + + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(oldInputEither.right().value())); + } + JSONObject jobject = new JSONObject(); + jobject.put("get_input", input.getName()); + InputDefinition oldInput = oldInputEither.left().value(); + + ComponentInstanceInput inputValue = new ComponentInstanceInput(oldInput, jobject.toJSONString(), null); + Integer index = counterRes.left().value(); + + Either eitherStatus = componentInstanceOperation.addInputValueToResourceInstance(inputValue, compInstId, index, true); + + if (eitherStatus.isRight()) { + log.error("Failed to add input value {} to resource instance {} in Graph. status is {}", inputValue, compInstId, eitherStatus.right().value().name()); + + return Either.right(eitherStatus.right().value()); + } + ComponentInstanceInput inputValueData = eitherStatus.left().value(); + + // ComponentInstanceInput propertyValueResult = + // buildResourceInstanceInput(propertyValueData, + // inputValue); + // log.debug("The returned ResourceInstanceProperty is " + // + propertyValueResult); + + String inputName = input.getName(); + input.setSchema(oldInputEither.left().value().getSchema()); + input.setDefaultValue(oldInput.getDefaultValue()); + input.setConstraints(oldInput.getConstraints()); + input.setDescription(oldInput.getDescription()); + input.setHidden(oldInput.isHidden()); + input.setImmutable(oldInput.isImmutable()); + input.setDefinition(oldInput.isDefinition()); + input.setRequired(oldInput.isRequired()); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(input, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property {} is invalid. Status is {}", input, validateAndUpdateProperty); + return Either.right(validateAndUpdateProperty); + } + + Either addPropertyToGraph = addInputToGraph(inputName, input, resourceId, nodeType); + + if (addPropertyToGraph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToGraph.right().value())); + } + InputDefinition createdInputyDefinition = convertInputDataToInputDefinition(addPropertyToGraph.left().value()); + createdInputyDefinition.setName(inputName); + createdInputyDefinition.setParentUniqueId(resourceId); + + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), createdInputyDefinition.getName()); + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), compInstId); + + GraphNode propertyData = new UniqueIdData(NodeTypeEnum.InputValue, inputValueData.getValueUniqueUid()); + + Either addPropRefResult = titanGenericDao.createRelation(addPropertyToGraph.left().value(), propertyData, GraphEdgeLabels.GET_INPUT, props); + + if (addPropRefResult.isRight()) { + TitanOperationStatus status = addPropRefResult.right().value(); + String description = "Failed to associate input " + addPropertyToGraph.left().value().getUniqueId() + " to input value " + inputValueData.getUniqueId() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ASSOCIATING_INPUT_TO_PROP, description, ErrorSeverity.ERROR); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + resList.add(createdInputyDefinition); + + } + } + + } + } + return Either.left(resList); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java new file mode 100644 index 0000000000..0d29c18a95 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java @@ -0,0 +1,1308 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import org.apache.cassandra.transport.Event.StatusChange; +import org.apache.commons.lang3.tuple.ImmutablePair; +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.GraphNode; +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.elements.InterfaceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +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.operations.api.IInterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.InterfaceData; +import org.openecomp.sdc.be.resources.data.OperationData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("interface-operation") +public class InterfaceLifecycleOperation implements IInterfaceLifecycleOperation { + + private static Logger log = LoggerFactory.getLogger(InterfaceLifecycleOperation.class.getName()); + + public InterfaceLifecycleOperation() { + super(); + } + + @javax.annotation.Resource + private ArtifactOperation artifactOperation; + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @Override + public Either addInterfaceToResource(InterfaceDefinition interf, + String resourceId, String interfaceName) { + + return addInterfaceToResource(interf, resourceId, interfaceName, false); + } + + @Override + public Either addInterfaceToResource(InterfaceDefinition interf, + String resourceId, String interfaceName, boolean inTransaction) { + + return createInterfaceOnResource(interf, resourceId, interfaceName, true, inTransaction); + + } + + private Either addOperationToGraph(InterfaceDefinition interf, String opName, + Operation op, InterfaceData interfaceData) { + + op.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId((String) interfaceData.getUniqueId(), opName)); + OperationData operationData = new OperationData(op); + + log.debug("Before adding operation to graph {}", operationData); + Either createOpNodeResult = titanGenericDao.createNode(operationData, + OperationData.class); + log.debug("After adding operation to graph {}", operationData); + + if (createOpNodeResult.isRight()) { + TitanOperationStatus opStatus = createOpNodeResult.right().value(); + log.error("Failed to add operation {} to graph. Status is {}", opName, opStatus); + return Either.right(opStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), opName); + Either createRelResult = titanGenericDao.createRelation(interfaceData, + operationData, GraphEdgeLabels.INTERFACE_OPERATION, props); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createOpNodeResult.right().value(); + log.error("Failed to associate operation {} to property {} in graph. Status is {}", interfaceData.getUniqueId(), opName, operationStatus); + + return Either.right(operationStatus); + } + + return Either.left(createOpNodeResult.left().value()); + + } + + private Either addOperationToGraph(InterfaceDefinition interf, String opName, + Operation op, TitanVertex interfaceVertex) { + + String interfaceId = (String) titanGenericDao.getProperty(interfaceVertex, + GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + op.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(interfaceId, opName)); + OperationData operationData = new OperationData(op); + + log.debug("Before adding operation to graph {}", operationData); + Either createOpNodeResult = titanGenericDao.createNode(operationData); + + if (createOpNodeResult.isRight()) { + TitanOperationStatus opStatus = createOpNodeResult.right().value(); + log.error("Failed to add operation {} to graph. status is {}", opName, opStatus); + return Either.right(opStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), opName); + TitanVertex operationVertex = createOpNodeResult.left().value(); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(interfaceVertex, operationVertex, + GraphEdgeLabels.INTERFACE_OPERATION, props); + + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate operation {} to property {} in graph. status is {}", interfaceId, opName, + createRelResult); + + return Either.right(createRelResult); + } + return Either.left(operationVertex); + } + + private InterfaceDefinition convertInterfaceDataToInterfaceDefinition(InterfaceData interfaceData) { + + log.debug("The object returned after create interface is {}", interfaceData); + + InterfaceDefinition interfaceDefResult = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition()); + + return interfaceDefResult; + + } + + private Operation convertOperationDataToOperation(OperationData operationData) { + + log.debug("The object returned after create operation is {}", operationData); + + Operation operationDefResult = new Operation(operationData.getOperationDataDefinition()); + + return operationDefResult; + + } + + private Either addInterfaceToGraph(InterfaceDefinition interfaceInfo, + String interfaceName, String resourceId) { + + InterfaceData interfaceData = new InterfaceData(interfaceInfo); + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + + String interfaceNameSplitted = getShortInterfaceName(interfaceInfo); + + interfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted)); + + Either existInterface = titanGenericDao + .getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class); + + if (existInterface.isRight()) { + + return createInterfaceNodeAndRelation(interfaceNameSplitted, resourceId, interfaceData, resourceData); + } else { + log.debug("Interface {} already exist", interfaceData.getUniqueId()); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + } + + private Either addInterfaceToGraph(InterfaceDefinition interfaceInfo, + String interfaceName, String resourceId, TitanVertex metadataVertex) { + + InterfaceData interfaceData = new InterfaceData(interfaceInfo); + + String interfaceNameSplitted = getShortInterfaceName(interfaceInfo); + + interfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted)); + + Either existInterface = titanGenericDao + .getVertexByProperty(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId()); + + if (existInterface.isRight()) { + + return createInterfaceNodeAndRelation(interfaceNameSplitted, resourceId, interfaceData, metadataVertex); + } else { + log.debug("Interface {} already exist", interfaceData.getUniqueId()); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + } + + private Either createInterfaceNodeAndRelation(String interfaceName, + String resourceId, InterfaceData interfaceData, ResourceMetadataData resourceData) { + log.debug("Before adding interface to graph {}", interfaceData); + Either createNodeResult = titanGenericDao.createNode(interfaceData, + InterfaceData.class); + log.debug("After adding property to graph {}", interfaceData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add interface {} to graph. Status is {}", interfaceName, operationStatus); + return Either.right(operationStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName); + Either createRelResult = titanGenericDao.createRelation(resourceData, + interfaceData, GraphEdgeLabels.INTERFACE, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate resource {} to property {} in graph. Status is {}", resourceId, interfaceName, operationStatus); + + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + } + + private Either createInterfaceNodeAndRelation(String interfaceName, + String resourceId, InterfaceData interfaceData, TitanVertex metadataVertex) { + log.debug("Before adding interface to graph {}", interfaceData); + Either createNodeResult = titanGenericDao.createNode(interfaceData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add interface {} to graph. status is {}", interfaceName, operationStatus); + return Either.right(operationStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName); + TitanVertex interfaceVertex = createNodeResult.left().value(); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(metadataVertex, interfaceVertex, + GraphEdgeLabels.INTERFACE, props); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, + interfaceName, createRelResult); + } + return Either.left(interfaceVertex); + } + + private Either createOperationNodeAndRelation(String operationName, + OperationData operationData, InterfaceData interfaceData) { + log.debug("Before adding operation to graph {}", operationData); + Either createNodeResult = titanGenericDao.createNode(operationData, + OperationData.class); + log.debug("After adding operation to graph {}", interfaceData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add interfoperationce {} to graph. Status is {}", operationName, operationStatus); + return Either.right(operationStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), operationName); + Either createRelResult = titanGenericDao.createRelation(interfaceData, + operationData, GraphEdgeLabels.INTERFACE_OPERATION, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate operation {} to interface {} in graph. Status is {}", operationName, interfaceData.getUniqueId(), operationStatus); + + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + } + + // @Override + // public Either getInterface( + // String interfaceId) { + // + // /* + // * Either getResult = + // * this.titanGenericDao + // * .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), + // * interfaceId, InterfaceData.class); if (getResult.isLeft()) { + // * InterfaceData propertyData = getResult.left().value(); return + // * Either.left(convertPropertyDataToPropertyDefinition(propertyData)); } + // * else { TitanOperationStatus titanStatus = getResult.right().value(); + // * log.debug("Node with id {} was not found in the graph. Status: {}", propertyId, titanStatus); + // * StorageOperationStatus storageOperationStatus = + // * DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + // * return Either.right(storageOperationStatus); } + // */ + // return null; + // } + + // @Override + // public Either getInterface( + // String interfaceId, boolean inTransaction) { + // // TODO Auto-generated method stub + // return null; + // } + + @Override + public Either, StorageOperationStatus> getAllInterfacesOfResource( + String resourceIdn, boolean recursively) { + return getAllInterfacesOfResource(resourceIdn, recursively, false); + } + + @Override + public Either, StorageOperationStatus> getAllInterfacesOfResource( + String resourceId, boolean recursively, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + Map interfaces = new HashMap(); + try { + if ((resourceId == null) || resourceId.isEmpty()) { + log.error("resourceId is empty"); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + TitanOperationStatus findInterfacesRes = TitanOperationStatus.GENERAL_ERROR; + if (recursively) { + findInterfacesRes = findAllInterfacesRecursively(resourceId, interfaces); + } else { + findInterfacesRes = findAllInterfacesNotRecursively(resourceId, interfaces); + } + if (!findInterfacesRes.equals(TitanOperationStatus.OK)) { + log.error("Failed to get all interfaces of resource {}. Status is {}", resourceId, findInterfacesRes); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findInterfacesRes)); + return result; + } + result = Either.left(interfaces); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private TitanOperationStatus findAllInterfacesNotRecursively(String resourceId, + Map interfaces) { + + Either>, TitanOperationStatus> interfaceNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class); + + if (interfaceNodes.isRight()) { + TitanOperationStatus status = interfaceNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return status; + } + } else { + List> interfaceList = interfaceNodes.left().value(); + if (interfaceList != null) { + for (ImmutablePair interfacePair : interfaceList) { + String interfaceUniqueId = (String) interfacePair.getKey().getUniqueId(); + Either interfaceNameRes = getPropertyValueFromEdge( + interfacePair.getValue(), GraphPropertiesDictionary.NAME); + if (interfaceNameRes.isRight()) { + log.error("The requirement name is missing on the edge of requirement {}", interfaceUniqueId); + return interfaceNameRes.right().value(); + } + String interfaceName = interfaceNameRes.left().value(); + Either interfaceDefRes = getNonRecursiveInterface( + interfacePair.getKey()); + if (interfaceDefRes.isRight()) { + TitanOperationStatus status = interfaceDefRes.right().value(); + log.error("Failed to get interface actions of interface {}", interfaceUniqueId); + return status; + } + + InterfaceDefinition interfaceDefinition = interfaceDefRes.left().value(); + if (true == interfaces.containsKey(interfaceName)) { + log.debug("The interface {} was already defined in derived resource. add not overriden operations", interfaceName); + InterfaceDefinition existInterface = interfaces.get(interfaceName); + addMissingOperationsToInterface(interfaceDefinition, existInterface); + } else { + interfaces.put(interfaceName, interfaceDefinition); + } + + } + } + } + return TitanOperationStatus.OK; + } + + public TitanOperationStatus findAllInterfacesRecursively(String resourceId, + Map interfaces) { + + TitanOperationStatus findAllInterfacesNotRecursively = findAllInterfacesNotRecursively(resourceId, interfaces); + if (!findAllInterfacesNotRecursively.equals(TitanOperationStatus.OK)) { + log.error("failed to get interfaces for resource {}. Status is {}", resourceId, findAllInterfacesNotRecursively); + } + + Either, TitanOperationStatus> parentNodes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (parentNodesStatus == TitanOperationStatus.NOT_FOUND) { + log.debug("Finish to lookup for parnet interfaces"); + return TitanOperationStatus.OK; + } else { + log.error("Failed to find parent interfaces of resource {}. Status is {}", resourceId, parentNodesStatus); + return parentNodesStatus; + } + } + ImmutablePair parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findAllInterfacesRecursively(parentUniqueId, interfaces); + + if (addParentIntStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch all interfaces of resource {}", parentUniqueId); + return addParentIntStatus; + } + + return TitanOperationStatus.OK; + } + + private Either getPropertyValueFromEdge(GraphEdge edge, + GraphPropertiesDictionary property) { + Map edgeProps = edge.getProperties(); + String interfaceName = null; + if (edgeProps != null) { + interfaceName = (String) edgeProps.get(property.getProperty()); + if (interfaceName == null) { + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + } else { + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + return Either.left(interfaceName); + } + + private Either getNonRecursiveInterface(InterfaceData interfaceData) { + + log.debug("Going to fetch the operations associate to interface {}", interfaceData.getUniqueId()); + InterfaceDefinition interfaceDefinition = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition()); + + String interfaceId = interfaceData.getUniqueId(); + Either>, TitanOperationStatus> operationsRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), interfaceId, + GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class); + + if (operationsRes.isRight()) { + TitanOperationStatus status = operationsRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } else { + return Either.left(interfaceDefinition); + } + } + + List> operationList = operationsRes.left().value(); + if (operationList != null && !operationList.isEmpty()) { + for (ImmutablePair operationPair : operationList) { + Operation operation = new Operation(operationPair.getKey().getOperationDataDefinition()); + Either operationNameRes = getPropertyValueFromEdge( + operationPair.getValue(), GraphPropertiesDictionary.NAME); + if (operationNameRes.isRight()) { + log.error("The operation name is missing on the edge of operation {}", operationPair.getKey().getUniqueId()); + return Either.right(operationNameRes.right().value()); + } + String operationName = operationNameRes.left().value(); + findOperationImplementation(operation); + interfaceDefinition.getOperations().put(operationName, operation); + } + } + + return Either.left(interfaceDefinition); + } + + private StorageOperationStatus findOperationImplementation(Operation operation) { + + String operationId = operation.getUniqueId(); + Either, StorageOperationStatus> artifactsRes = artifactOperation + .getArtifacts(operationId, NodeTypeEnum.InterfaceOperation, true); + if (artifactsRes.isRight() || artifactsRes.left().value() == null) { + log.error("failed to get artifact from graph for operation id {}. status is {}", operationId, + artifactsRes.right().value()); + return artifactsRes.right().value(); + } else { + Map artifacts = artifactsRes.left().value(); + Iterator iter = artifacts.keySet().iterator(); + + if (iter.hasNext()) { + operation.setImplementation(artifacts.get(iter.next())); + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus addMissingOperationsToInterface(InterfaceDefinition interfaceDefinition, + InterfaceDefinition existInterface) { + Map existOperations = existInterface.getOperations(); + Map operations = interfaceDefinition.getOperations(); + if (operations != null && !operations.isEmpty()) { + Set> operationsSet = operations.entrySet(); + for (Entry operation : operationsSet) { + if (!existOperations.containsKey(operation.getKey())) { + existOperations.put(operation.getKey(), operation.getValue()); + } + } + } + return StorageOperationStatus.OK; + } + + @Override + public Either updateInterfaceOperation(String resourceId, String interfaceName, + String operationName, Operation interf) { + + return updateInterfaceOperation(resourceId, interfaceName, operationName, interf, false); + } + + @Override + public Either updateInterfaceOperation(String resourceId, String interfaceName, + String operationName, Operation operation, boolean inTransaction) { + Either status = updateOperationOnGraph(operation, resourceId, interfaceName, + operationName); + + /* + * if (status.isRight()) { if (false == inTransaction) { + * titanGenericDao.rollback(); } log.error("Failed to update operation " + * + operationName + " of interfaceName " + interfaceName + + * " of resource" + resourceId); return Either.right(DaoStatusConverter + * .convertTitanStatusToStorageStatus(status.right().value())); } else { + * if (false == inTransaction) { titanGenericDao.commit(); } + * OperationData operationData = status.left().value(); + * + * Operation operationDefResult = + * convertOperationDataToOperation(operationData); + * + * + * log.debug("The returned OperationDefintion is {}", operationDefResult); return Either.left(operationDefResult); } + */ + return status; + } + + private Either updateOperationOnGraph(Operation operation, String resourceId, + String interfaceName, String operationName) { + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, + GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class); + + if (childrenNodes.isRight()) { + /* + * InterfaceDefinition intDef = new InterfaceDefinition(); + * intDef.setType(interfaceName); Map opMap = new + * HashMap(); opMap.put(operationName, + * operation); intDef.setOperations(opMap); + * Either statusRes = + * this .createInterfaceOnResource(intDef, resourceId, + * interfaceName, true); if (statusRes.isRight()) return + * Either.right(statusRes.right().value()); else { + * InterfaceDefinition newDef = statusRes.left().value(); Operation + * res = newDef.getOperations().get(operationName); return + * Either.left(res); } + */ + return updateOperationFromParentNode(operation, resourceId, interfaceName, operationName); + + } else { + return updateExistingOperation(resourceId, operation, interfaceName, operationName, childrenNodes); + + } + + } + + private Either updateExistingOperation(String resourceId, Operation operation, + String interfaceName, String operationName, + Either>, TitanOperationStatus> childrenNodes) { + Operation newOperation = null; + StorageOperationStatus storageOperationStatus = StorageOperationStatus.GENERAL_ERROR; + + for (ImmutablePair interfaceDataNode : childrenNodes.left().value()) { + + GraphEdge interfaceEdge = interfaceDataNode.getRight(); + Map interfaceEdgeProp = interfaceEdge.getProperties(); + InterfaceData interfaceData = interfaceDataNode.getKey(); + + if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) { + Either>, TitanOperationStatus> operationRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) interfaceDataNode.getLeft().getUniqueId(), GraphEdgeLabels.INTERFACE_OPERATION, + NodeTypeEnum.InterfaceOperation, OperationData.class); + if (operationRes.isRight()) { + log.error("Failed to find operation {} on interface {}", operationName, interfaceName); + return Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value())); + } else { + List> operations = operationRes.left().value(); + for (ImmutablePair operationPairEdge : operations) { + GraphEdge opEdge = operationPairEdge.getRight(); + OperationData opData = operationPairEdge.getLeft(); + Map opEdgeProp = opEdge.getProperties(); + if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) { + ArtifactDefinition artifact = operation.getImplementation(); + Either, TitanOperationStatus> artifactRes = titanGenericDao + .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) opData.getUniqueId(), GraphEdgeLabels.ARTIFACT_REF, + NodeTypeEnum.ArtifactRef, ArtifactData.class); + Either artStatus; + if (artifactRes.isRight()) { + artStatus = artifactOperation.addArifactToComponent(artifact, + (String) operationPairEdge.getLeft().getUniqueId(), + NodeTypeEnum.InterfaceOperation, true, true); + } else { + artStatus = artifactOperation.updateArifactOnResource(artifact, + (String) operationPairEdge.getLeft().getUniqueId(), + (String) artifactRes.left().value().getLeft().getUniqueId(), + NodeTypeEnum.InterfaceOperation, true); + } + if (artStatus.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add artifact {}", operationName, interfaceName); + return Either.right(artStatus.right().value()); + } else { + newOperation = this.convertOperationDataToOperation(opData); + newOperation.setImplementation(artStatus.left().value()); + + } + + } + + } + if (newOperation == null) { + Either parentInterfaceStatus = findInterfaceOnParentNode( + resourceId, interfaceName); + if (parentInterfaceStatus.isRight()) { + log.debug("Interface {} not exist", interfaceName); + return Either.right(DaoStatusConverter + .convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value())); + } + + InterfaceData parentInterfaceData = parentInterfaceStatus.left().value(); + Either>, TitanOperationStatus> opRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) parentInterfaceData.getUniqueId(), GraphEdgeLabels.INTERFACE_OPERATION, + NodeTypeEnum.InterfaceOperation, OperationData.class); + if (opRes.isRight()) { + log.error("Failed to find operation {} on interface", operationName, interfaceName); + return Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value())); + + } else { + List> parentOperations = opRes.left().value(); + for (ImmutablePair operationPairEdge : parentOperations) { + GraphEdge opEdge = operationPairEdge.getRight(); + OperationData opData = operationPairEdge.getLeft(); + Map opEdgeProp = opEdge.getProperties(); + if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()) + .equals(operationName)) { + return copyAndCreateNewOperation(operation, interfaceName, operationName, null, + interfaceData, operationRes, opData); + } + } + } + + } + + } + + } else { + // not found + storageOperationStatus = StorageOperationStatus.ARTIFACT_NOT_FOUND; + } + + } + if (newOperation == null) + return Either.right(storageOperationStatus); + else + return Either.left(newOperation); + } + + private Either copyAndCreateNewOperation(Operation operation, + String interfaceName, String operationName, Operation newOperation, InterfaceData interfaceData, + Either>, TitanOperationStatus> operationRes, + OperationData opData) { + OperationDataDefinition opDataInfo = opData.getOperationDataDefinition(); + OperationDataDefinition newOperationInfo = new OperationDataDefinition(opDataInfo); + newOperationInfo.setUniqueId( + UniqueIdBuilder.buildPropertyUniqueId(interfaceData.getUniqueId(), operationName.toLowerCase())); + OperationData newopData = new OperationData(newOperationInfo); + Either operationStatus = createOperationNodeAndRelation(operationName, + newopData, interfaceData); + if (operationStatus.isRight()) { + log.error("Failed to create operation {} on interface {}", operationName, interfaceName); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value())); + } + ArtifactDefinition artifact = operation.getImplementation(); + if (artifact != null) { + Either artStatus = artifactOperation.addArifactToComponent( + artifact, (String) operationStatus.left().value().getUniqueId(), NodeTypeEnum.InterfaceOperation, + true, true); + if (artStatus.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add artifact {} to interface {}", operationName, interfaceName); + } else { + newOperation = this.convertOperationDataToOperation(opData); + newOperation.setImplementation(artStatus.left().value()); + + } + } + return Either.left(newOperation); + } + + private Either updateOperationFromParentNode(Operation operation, + String resourceId, String interfaceName, String operationName) { + // Operation newOperation = null; + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + Either parentInterfaceStatus = findInterfaceOnParentNode(resourceId, + interfaceName); + if (parentInterfaceStatus.isRight()) { + log.debug("Interface {} not exist", interfaceName); + return Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value())); + } + + InterfaceData interfaceData = parentInterfaceStatus.left().value(); + InterfaceDataDefinition intDataDefinition = interfaceData.getInterfaceDataDefinition(); + InterfaceDataDefinition newInterfaceInfo = new InterfaceDataDefinition(intDataDefinition); + + String interfaceNameSplitted = getShortInterfaceName(intDataDefinition); + + newInterfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted)); + InterfaceData updatedInterfaceData = new InterfaceData(newInterfaceInfo); + Either createStatus = createInterfaceNodeAndRelation(interfaceName, + resourceId, updatedInterfaceData, resourceData); + if (createStatus.isRight()) { + log.debug("failed to create interface node {} on resource {}", interfaceName, resourceId); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createStatus.right().value())); + } + + InterfaceData newInterfaceNode = createStatus.left().value(); + Either createRelResult = titanGenericDao.createRelation(newInterfaceNode, + interfaceData, GraphEdgeLabels.DERIVED_FROM, null); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate interface {} to interface {} in graph. Status is {}", interfaceData.getUniqueId(), newInterfaceNode.getUniqueId(), operationStatus); + + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus)); + } + Either>, TitanOperationStatus> operationRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) interfaceData.getUniqueId(), GraphEdgeLabels.INTERFACE_OPERATION, + NodeTypeEnum.InterfaceOperation, OperationData.class); + if (operationRes.isRight()) { + log.error("Failed to find operation {} on interface {}", operationName, interfaceName); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value())); + + } else { + List> operations = operationRes.left().value(); + for (ImmutablePair operationPairEdge : operations) { + GraphEdge opEdge = operationPairEdge.getRight(); + OperationData opData = operationPairEdge.getLeft(); + Map opEdgeProp = opEdge.getProperties(); + if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) { + + return copyAndCreateNewOperation(operation, interfaceName, operationName, null, // changed + // from + // newOperation + newInterfaceNode, operationRes, opData); + + } + } + } + // if(newOperation == null) + return Either.right(StorageOperationStatus.GENERAL_ERROR); + // else + // return Either.left(newOperation); + } + + private Either findInterfaceOnParentNode(String resourceId, + String interfaceName) { + + Either, TitanOperationStatus> parentRes = titanGenericDao + .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.Resource, ResourceMetadataData.class); + if (parentRes.isRight()) { + log.debug("interface {} not found", interfaceName); + return Either.right(parentRes.right().value()); + } + ImmutablePair parenNode = parentRes.left().value(); + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + parenNode.getKey().getMetadataDataDefinition().getUniqueId(), GraphEdgeLabels.INTERFACE, + NodeTypeEnum.Interface, InterfaceData.class); + if (childrenNodes.isRight()) { + return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), + interfaceName); + + } else { + for (ImmutablePair interfaceDataNode : childrenNodes.left().value()) { + + GraphEdge interfaceEdge = interfaceDataNode.getRight(); + Map interfaceEdgeProp = interfaceEdge.getProperties(); + + if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) { + return Either.left(interfaceDataNode.getKey()); + } + + } + return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), + interfaceName); + } + + } + + @Override + public Either createInterfaceOnResource(InterfaceDefinition interf, + String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction) { + + Either status = addInterfaceToGraph(interf, interfaceName, resourceId); + + if (status.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add interface {} to resource {}", interfaceName, resourceId); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } else { + + if (false == inTransaction) { + titanGenericDao.commit(); + } + InterfaceData interfaceData = status.left().value(); + + InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData); + Map operations = interf.getOperations(); + if (operations != null && !operations.isEmpty()) { + Set opNames = operations.keySet(); + Map newOperations = new HashMap(); + for (String operationName : opNames) { + + Operation op = operations.get(operationName); + Either opStatus = addOperationToGraph(interf, operationName, + op, interfaceData); + if (status.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add operation {} to interface {}", operationName, interfaceName); + } else if (status.isLeft()) { + if (false == inTransaction) { + titanGenericDao.commit(); + } + OperationData opData = opStatus.left().value(); + Operation newOperation = this.convertOperationDataToOperation(opData); + + ArtifactDefinition art = op.getImplementation(); + if (art != null) { + Either artRes = artifactOperation + .addArifactToComponent(art, (String) opData.getUniqueId(), + NodeTypeEnum.InterfaceOperation, failIfExist, true); + if (artRes.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add artifact {} to interface {}", operationName, interfaceName); + } else { + newOperation.setImplementation(artRes.left().value()); + } + newOperations.put(operationName, newOperation); + } + } + } + interfaceDefResult.setOperations(newOperations); + } + log.debug("The returned InterfaceDefintion is {}", interfaceDefResult); + return Either.left(interfaceDefResult); + } + + } + + @Override + public StorageOperationStatus createInterfaceOnResource(InterfaceDefinition interf, String resourceId, + String interfaceName, boolean failIfExist, boolean inTransaction, TitanVertex metadataVertex) { + + Either interfaceResult = addInterfaceToGraph(interf, interfaceName, + resourceId, metadataVertex); + + if (interfaceResult.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to add interface {} to resource {}", interfaceName, resourceId); + return DaoStatusConverter.convertTitanStatusToStorageStatus(interfaceResult.right().value()); + } else { + + if (false == inTransaction) { + titanGenericDao.commit(); + } + TitanVertex interfaceVertex = interfaceResult.left().value(); + + // InterfaceDefinition interfaceDefResult = + // convertInterfaceDataToInterfaceDefinition(interfaceData); + Map operations = interf.getOperations(); + if (operations != null && !operations.isEmpty()) { + Set opNames = operations.keySet(); + for (String operationName : opNames) { + + Operation op = operations.get(operationName); + Either operationResult = addOperationToGraph(interf, + operationName, op, interfaceVertex); + if (operationResult.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to add operation {} to interface {}", operationName, interfaceName); + return DaoStatusConverter.convertTitanStatusToStorageStatus(operationResult.right().value()); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + TitanVertex operationVertex = operationResult.left().value(); + + ArtifactDefinition art = op.getImplementation(); + if (art != null) { + String opId = (String) titanGenericDao.getProperty(operationVertex, + GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + StorageOperationStatus artRes = artifactOperation.addArifactToComponent(art, opId, + NodeTypeEnum.InterfaceOperation, failIfExist, operationVertex); + if (!artRes.equals(StorageOperationStatus.OK)) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to add artifact {} to interface {}", operationName, interfaceName); + return artRes; + } + } + } + } + } + return StorageOperationStatus.OK; + } + + } + + @Override + public Either deleteInterfaceOperation(String resourceId, String interfaceName, + String operationId) { + return deleteInterfaceOperation(resourceId, interfaceName, operationId, false); + } + + @Override + public Either deleteInterfaceOperation(String resourceId, String interfaceName, + String operationId, boolean inTransaction) { + + Either status = removeOperationOnGraph(resourceId, interfaceName, operationId); + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to delete operation {} of interface {} resource {}", operationId, interfaceName, resourceId); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + + Operation opDefResult = status.left().value();// convertOperationDataToOperation(operationData); + log.debug("The returned Operation is {}", opDefResult); + return Either.left(opDefResult); + } + + } + + @Override + public Either deleteInterfaceOfResourceOnGraph(String resourceId, + InterfaceDefinition interfaceDef, boolean inTransaction) { + + Map operations = interfaceDef.getOperations(); + String interfaceNameSplitted = getShortInterfaceName(interfaceDef); + if (operations != null) { + for (Entry entry : operations.entrySet()) { + + Operation op = entry.getValue(); + Either removeOperationFromResource = deleteInterfaceOperation( + resourceId, interfaceNameSplitted, op.getUniqueId(), true); + if (removeOperationFromResource.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to delete operation {} of interface {} resource {}", op.getUniqueId(), interfaceDef.getType(), resourceId); + return Either.right(removeOperationFromResource.right().value()); + } + } + } + return Either.left(interfaceDef); + + } + + private Either removeOperationOnGraph(String resourceId, String interfaceName, + String operationId) { + log.debug("Before deleting operation from graph {}", operationId); + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, + GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class); + + if (childrenNodes.isRight()) { + log.debug("Not found interface {}", interfaceName); + return Either.right(childrenNodes.right().value()); + } + OperationData opData = null; + for (ImmutablePair interfaceDataNode : childrenNodes.left().value()) { + + GraphEdge interfaceEdge = interfaceDataNode.getRight(); + Map interfaceEdgeProp = interfaceEdge.getProperties(); + + String interfaceSplitedName = splitType(interfaceName); + + if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceSplitedName)) { + Either>, TitanOperationStatus> operationRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) interfaceDataNode.getLeft().getUniqueId(), GraphEdgeLabels.INTERFACE_OPERATION, + NodeTypeEnum.InterfaceOperation, OperationData.class); + if (operationRes.isRight()) { + log.error("Failed to find operation {}", operationId, interfaceName); + return Either.right(operationRes.right().value()); + } + List> operations = operationRes.left().value(); + + for (ImmutablePair operationPairEdge : operations) { + + opData = operationPairEdge.getLeft(); + if (opData.getUniqueId().equals(operationId)) { + + Either, TitanOperationStatus> artifactRes = titanGenericDao + .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) operationPairEdge.getLeft().getUniqueId(), + GraphEdgeLabels.ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class); + Either arStatus = null; + if (artifactRes.isLeft()) { + ArtifactData arData = artifactRes.left().value().getKey(); + arStatus = artifactOperation.removeArifactFromResource( + (String) operationPairEdge.getLeft().getUniqueId(), (String) arData.getUniqueId(), + NodeTypeEnum.InterfaceOperation, true, true); + if (arStatus.isRight()) { + log.debug("failed to delete artifact {}", arData.getUniqueId()); + return Either.right(TitanOperationStatus.INVALID_ID); + } + } + Either deleteOpStatus = titanGenericDao.deleteNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InterfaceOperation), opData.getUniqueId(), + OperationData.class); + if (deleteOpStatus.isRight()) { + log.debug("failed to delete operation {}", opData.getUniqueId()); + return Either.right(TitanOperationStatus.INVALID_ID); + } + opData = deleteOpStatus.left().value(); + Operation operation = new Operation(opData.getOperationDataDefinition()); + if (arStatus != null) { + operation.setImplementation(arStatus.left().value()); + } + if (operations.size() <= 1) { + Either deleteInterfaceStatus = titanGenericDao + .deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), + interfaceDataNode.left.getUniqueId(), InterfaceData.class); + if (deleteInterfaceStatus.isRight()) { + log.debug("failed to delete interface {}", interfaceDataNode.left.getUniqueId()); + return Either.right(TitanOperationStatus.INVALID_ID); + } + + } + + return Either.left(operation); + + } + } + } + } + + log.debug("Not found operation {}", interfaceName); + return Either.right(TitanOperationStatus.INVALID_ID); + // } + + } + + private String splitType(String interfaceName) { + String interfaceSplittedName; + String[] packageName = interfaceName.split("\\."); + + if (packageName.length == 0) { + interfaceSplittedName = interfaceName; + } else { + interfaceSplittedName = packageName[packageName.length - 1]; + } + + return interfaceSplittedName.toLowerCase(); + } + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + public void setArtifactOperation(ArtifactOperation artifactOperation) { + this.artifactOperation = artifactOperation; + } + + @Override + public Either createInterfaceType(InterfaceDefinition interf, + boolean inTransaction) { + Either result = null; + try { + + InterfaceData interfaceData = new InterfaceData(interf); + interf.setUniqueId(interf.getType().toLowerCase()); + + Either existInterface = titanGenericDao + .getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class); + + if (existInterface.isLeft()) { + // already exist + log.debug("Interface type already exist {}", interfaceData); + result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS); + return result; + } + + log.debug("Before adding interface type to graph {}", interfaceData); + Either createNodeResult = titanGenericDao.createNode(interfaceData, + InterfaceData.class); + log.debug("After adding property type to graph {}", interfaceData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add interface {} to graph. Status is {}", interf.getType(), operationStatus); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus)); + return result; + } + + InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData); + Map operations = interf.getOperations(); + + if (operations != null && !operations.isEmpty()) { + Map newOperations = new HashMap(); + + for (Map.Entry operation : operations.entrySet()) { + Either opStatus = addOperationToGraph(interf, + operation.getKey(), operation.getValue(), interfaceData); + if (opStatus.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add operation {} to interface {}", operation.getKey(), interf.getType()); + + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(opStatus.right().value())); + return result; + } else { + OperationData opData = opStatus.left().value(); + Operation newOperation = this.convertOperationDataToOperation(opData); + newOperations.put(operation.getKey(), newOperation); + } + } + interfaceDefResult.setOperations(newOperations); + } + result = Either.left(interfaceDefResult); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either getInterface(String interfaceId) { + Either getResult = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceId, InterfaceData.class); + if (getResult.isLeft()) { + InterfaceData interfaceData = getResult.left().value(); + return Either.left(convertInterfaceDataToInterfaceDefinition(interfaceData)); + } else { + TitanOperationStatus titanStatus = getResult.right().value(); + log.debug("Node with id {} was not found in the graph. Status: {}", interfaceId, titanStatus); + StorageOperationStatus storageOperationStatus = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanStatus); + return Either.right(storageOperationStatus); + } + } + + @Override + public StorageOperationStatus associateInterfaceToNode(GraphNode node, InterfaceDefinition interfaceDefinition, + TitanVertex metadataVertex) { + + Either interfaceData = titanGenericDao.getVertexByProperty( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceDefinition.getUniqueId()); + if (interfaceData.isRight()) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(interfaceData.right().value()); + } + + Map properties = new HashMap(); + + String interfaceName = getShortInterfaceName(interfaceDefinition); + + properties.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName.toLowerCase()); + TitanOperationStatus createRelation = titanGenericDao.createEdge(metadataVertex, interfaceData.left().value(), + GraphEdgeLabels.INTERFACE, properties); + if (!createRelation.equals(TitanOperationStatus.OK)) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation); + } + + return StorageOperationStatus.OK; + } + + public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition) { + String[] packageName = interfaceDefinition.getType().split("\\."); + String interfaceName; + if (packageName.length == 0) { + interfaceName = interfaceDefinition.getType(); + } else { + interfaceName = packageName[packageName.length - 1]; + } + return interfaceName.toLowerCase(); + } + + /** + * + */ + public Either createInterfaceType(InterfaceDefinition interf) { + return createInterfaceType(interf, false); + } + + @Override + public Either getSpecificOperation(String resourceId, String interfaceType, + String operationName) { + log.trace("Getting operation, resourceId {}, interfaceType {}, operationName {}", resourceId, interfaceType, + operationName); + Either, StorageOperationStatus> allInterfacesOfResource = getAllInterfacesOfResource( + resourceId, false); + if (allInterfacesOfResource.isRight() || allInterfacesOfResource.left().value() == null + || allInterfacesOfResource.left().value().get(interfaceType) == null) { + log.debug("Couldn't find interface definition of type {} for resource id {}", interfaceType, resourceId); + return Either.right(allInterfacesOfResource.right().value()); + } + InterfaceDefinition interfaceDefinition = allInterfacesOfResource.left().value().get(interfaceType); + Map operations = interfaceDefinition.getOperations(); + if (operations == null || operations.get(operationName) == null) { + log.debug("Couldn't find operation for operation name {}, interface type {}", operationName, interfaceType); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + return Either.left(operations.get(operationName)); + } + + @Override + public Either dissociateInterfaceFromNode(GraphNode node, + InterfaceDefinition interfaceDefinition) { + + Either interfaceData = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceDefinition.getUniqueId(), + InterfaceData.class); + if (interfaceData.isRight()) { + log.debug("Couldn't find interface {}", interfaceDefinition); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(interfaceData.right().value())); + } + + InterfaceData value = interfaceData.left().value(); + Either deleteRelation = titanGenericDao.deleteRelation(node, value, + GraphEdgeLabels.INTERFACE); + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + log.debug("Couldn't dissociate interface between node {} to node {}. Status is {}", node.getUniqueId(), + value.getUniqueId(), status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + return Either.left(interfaceDefinition); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperation.java new file mode 100644 index 0000000000..863975893c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperation.java @@ -0,0 +1,1143 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +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.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.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; +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.ComponentParametersView; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +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.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +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.be.resources.data.UniqueIdData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("lifecycle-operation") +public class LifecycleOperation implements ILifecycleOperation { + + public static final String VERSION_DELIMETER = "."; + public static final String VERSION_DELIMETER_REGEXP = "\\."; + + public LifecycleOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(LifecycleOperation.class.getName()); + + @javax.annotation.Resource + private ResourceOperation resourceOperation; + + @javax.annotation.Resource + private ServiceOperation serviceOperation; + + @javax.annotation.Resource + private ProductOperation productOperation; + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + public ResourceOperation getResourceOperation() { + return resourceOperation; + } + + public void setResourceOperation(ResourceOperation resourceOperation) { + this.resourceOperation = resourceOperation; + } + + public ServiceOperation getServiceOperation() { + return serviceOperation; + } + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType) { + if (NodeTypeEnum.Service.equals(componentType)) { + return serviceOperation; + } else if (NodeTypeEnum.Resource.equals(componentType)) { + return resourceOperation; + } else if (NodeTypeEnum.Product.equals(componentType)) { + return productOperation; + } + return null; + } + + public void setServiceOperation(ServiceOperation serviceOperation) { + this.serviceOperation = serviceOperation; + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either getComponentOwner(String resourceId, NodeTypeEnum nodeType, + boolean inTransaction) { + + Either result = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + + Either, TitanOperationStatus> parentNode = titanGenericDao.getParentNode( + UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, GraphEdgeLabels.STATE, NodeTypeEnum.User, + UserData.class); + + if (parentNode.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentNode.right().value())); + } + + ImmutablePair value = parentNode.left().value(); + + User owner = new User(value.left); + result = Either.left(owner); + + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + return result; + } + + @Override + public Either checkoutComponent(NodeTypeEnum nodeType, + Component component, User modifier, User currentOwner, boolean inTransaction) { + Either result = null; + + try { + // update old component + if (!component.getLifecycleState().equals(LifecycleStateEnum.CERTIFIED)) { + component.setHighestVersion(false); + ComponentOperation componentOperation = getComponentOperation(nodeType); + Either updateComponent = componentOperation + .updateComponent(component, inTransaction, titanGenericDao, component.getClass(), nodeType); + if (updateComponent.isRight()) { + StorageOperationStatus error = updateComponent.right().value(); + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, error); + return Either.right(error); + } + + StorageOperationStatus changeStateToLastState = changeStateRelation(nodeType, component.getUniqueId(), + currentOwner, GraphEdgeLabels.STATE, GraphEdgeLabels.LAST_STATE); + if (!changeStateToLastState.equals(StorageOperationStatus.OK)) { + result = Either.right(changeStateToLastState); + return result; + } + } + + // clone the component + result = cloneComponentForCheckout(component, nodeType, modifier); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, result.right().value()); + return result; + } + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + return result; + } + + private Either cloneComponentForCertified(Component component, + User modifier, Integer majorVersion) { + + // set new version + String certifiedVersion = (majorVersion + 1) + VERSION_DELIMETER + "0"; + component.setVersion(certifiedVersion); + component.setLifecycleState(LifecycleStateEnum.CERTIFIED); + component.setLastUpdateDate(null); + component.setLastUpdaterUserId(modifier.getUserId()); + component.setHighestVersion(true); + + ComponentOperation componentOperation = getComponentOperation(component.getComponentType().getNodeType()); + Either cloneComponentResult = componentOperation + .cloneComponent(component, certifiedVersion, LifecycleStateEnum.CERTIFIED, true); + + return cloneComponentResult; + } + + @Override + public Either undoCheckout(NodeTypeEnum nodeType, Component component, + User modifier, User currentOwner, boolean inTransaction) { + Either result = null; + ComponentOperation componentOperation = getComponentOperation(nodeType); + + // this is in case prevVersion is 0.0 - returning OOTB component + Component prevComponent = componentOperation.getDefaultComponent(); + try { + // find previous version + String[] versionParts = component.getVersion().split(VERSION_DELIMETER_REGEXP); + Integer minorVersion = Integer.parseInt(versionParts[1]) - 1; + String previousVersion = versionParts[0] + VERSION_DELIMETER + minorVersion; + + if (!previousVersion.equals("0.0")) { + Either updateOldResourceResult = updateOldComponentBeforeUndoCheckout( + componentOperation, prevComponent, component, previousVersion, nodeType, true); + if (updateOldResourceResult.isRight()) { + result = updateOldResourceResult; + return result; + } + prevComponent = updateOldResourceResult.left().value(); + } + + // delete the component + Either deleteResourceResult = componentOperation + .deleteComponent(component.getUniqueId(), true); + if (deleteResourceResult.isRight()) { + result = deleteResourceResult; + return result; + } + + // return the deleted resource + result = Either.left(prevComponent); + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either checkinComponent(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction) { + Either result = null; + try { + StorageOperationStatus updateCheckinInGraph = updateCheckinInGraph(nodeType, component.getUniqueId(), + component.getLifecycleState(), modifier, owner); + if (!updateCheckinInGraph.equals(StorageOperationStatus.OK)) { + log.error("failed to update state of resource {}. status={}", component.getUniqueId(), + updateCheckinInGraph); + return Either.right(updateCheckinInGraph); + } + LifecycleStateEnum state = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN; + ComponentParametersView componentParametersView = buildFilterForFetchComponentAfterChangeState(); + result = updateComponentMD(component, modifier, state, nodeType, componentParametersView); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + state, result.right().value()); + } + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private ComponentParametersView buildFilterForFetchComponentAfterChangeState() { + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreUsers(false); + // Used when we running multiple change states and want to use the + // result from another change + // state(LifecycleOperationTest.certificationStatusChange) + componentParametersView.setIgnoreCategories(false); + return componentParametersView; + } + + private StorageOperationStatus updateCheckinInGraph(NodeTypeEnum componentType, String componentId, + LifecycleStateEnum state, User modifier, User owner) { + + // check if we cancel rfc + if (state.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION)) { + + // remove last checkin + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + UniqueIdData resourceData = new UniqueIdData(componentType, componentId); + Either deleteResult = titanGenericDao + .deleteIncomingRelationByCriteria(resourceData, GraphEdgeLabels.LAST_STATE, props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + return StorageOperationStatus.INCONSISTENCY; + } + } + + // remove CHECKOUT relation + StorageOperationStatus removeUserToResourceRelation = removeUserToResourceRelation(componentType, + owner.getUserId(), componentId, GraphEdgeLabels.STATE); + if (!removeUserToResourceRelation.equals(StorageOperationStatus.OK)) { + return removeUserToResourceRelation; + } + + // create CHECKIN relation + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + StorageOperationStatus createUserToResourceRelation = createUserToResourceRelation(componentType, + modifier.getUserId(), componentId, GraphEdgeLabels.STATE, props); + if (!createUserToResourceRelation.equals(StorageOperationStatus.OK)) { + return createUserToResourceRelation; + } + + return StorageOperationStatus.OK; + } + + @Override + public Either requestCertificationComponent(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction) { + Either result = null; + try { + StorageOperationStatus updateRfcOnGraph = updateRfcOnGraph(nodeType, component.getUniqueId(), + component.getLifecycleState(), modifier, owner); + if (!updateRfcOnGraph.equals(StorageOperationStatus.OK)) { + log.error("failed to update state of resource {}. status={}", component.getUniqueId(), + updateRfcOnGraph); + return Either.right(updateRfcOnGraph); + } + + LifecycleStateEnum state = LifecycleStateEnum.READY_FOR_CERTIFICATION; + + ComponentParametersView componentParametersView = buildFilterForFetchComponentAfterChangeState(); + + result = updateComponentMD(component, modifier, state, nodeType, componentParametersView); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + state, result.right().value()); + return result; + } + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus updateRfcOnGraph(NodeTypeEnum componentType, String componentId, + LifecycleStateEnum state, User modifier, User owner) { + + if (state.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + // if this is atomic checkin + RFC: create checkin relation + + // remove CHECKOUT relation + StorageOperationStatus relationStatus = removeUserToResourceRelation(componentType, owner.getUserId(), + componentId, GraphEdgeLabels.STATE); + if (!relationStatus.equals(StorageOperationStatus.OK)) { + return relationStatus; + } + + // create CHECKIN relation + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + relationStatus = createUserToResourceRelation(componentType, modifier.getUserId(), componentId, + GraphEdgeLabels.LAST_STATE, props); + if (!relationStatus.equals(StorageOperationStatus.OK)) { + return relationStatus; + } + } else { + StorageOperationStatus changeStatus = changeRelationLabel(componentType, componentId, owner, + GraphEdgeLabels.STATE, GraphEdgeLabels.LAST_STATE); + if (!changeStatus.equals(StorageOperationStatus.OK)) { + return changeStatus; + } + } + + // create RFC relation + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + StorageOperationStatus changeRelationLabel = createUserToResourceRelation(componentType, modifier.getUserId(), + componentId, GraphEdgeLabels.STATE, props); + if (!changeRelationLabel.equals(StorageOperationStatus.OK)) { + return changeRelationLabel; + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus changeRelationLabel(NodeTypeEnum componentType, String componentId, User owner, + GraphEdgeLabels prevLabel, GraphEdgeLabels toLabel) { + UniqueIdData resourceV = new UniqueIdData(componentType, componentId); + UserData userV = new UserData(); + userV.setUserId(owner.getUserId()); + Either replaceRelationLabelResult = titanGenericDao + .replaceRelationLabel(userV, resourceV, prevLabel, toLabel); + if (replaceRelationLabelResult.isRight()) { + log.error("failed to replace label from last state to state"); + return DaoStatusConverter.convertTitanStatusToStorageStatus(replaceRelationLabelResult.right().value()); + } + return StorageOperationStatus.OK; + } + + @Override + public Either startComponentCertification(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction) { + Either result = null; + try { + StorageOperationStatus updateOnGraph = updateStartCertificationOnGraph(nodeType, component.getUniqueId(), + modifier, owner); + if (!updateOnGraph.equals(StorageOperationStatus.OK)) { + log.error("failed to update state of resource {}. status={}", component.getUniqueId(), updateOnGraph); + return Either.right(updateOnGraph); + } + + LifecycleStateEnum state = LifecycleStateEnum.CERTIFICATION_IN_PROGRESS; + ComponentParametersView componentParametersView = buildFilterForFetchComponentAfterChangeState(); + + result = updateComponentMD(component, modifier, state, nodeType, componentParametersView); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + state, result.right().value()); + } + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus updateStartCertificationOnGraph(NodeTypeEnum componentType, String componentId, + User modifier, User owner) { + StorageOperationStatus changeRelationLabel = changeRelationLabel(componentType, componentId, owner, + GraphEdgeLabels.STATE, GraphEdgeLabels.LAST_STATE); + if (!changeRelationLabel.equals(StorageOperationStatus.OK)) { + return changeRelationLabel; + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + StorageOperationStatus createUserToResourceRelation = createUserToResourceRelation(componentType, + modifier.getUserId(), componentId, GraphEdgeLabels.STATE, props); + if (!createUserToResourceRelation.equals(StorageOperationStatus.OK)) { + return createUserToResourceRelation; + } + return StorageOperationStatus.OK; + } + + @Override + public Either certifyComponent(NodeTypeEnum nodeType, + Component component, User modifier, User currentOwner, boolean inTransaction) { + Either result = null; + + try { + String resourceIdBeforeCertify = component.getUniqueId(); + String[] versionParts = component.getVersion().split(VERSION_DELIMETER_REGEXP); + Integer majorVersion = Integer.parseInt(versionParts[0]); + + // update old certified resource + if (majorVersion > 0) { + StorageOperationStatus updateLastCertifiedResource = StorageOperationStatus.OK; + updateLastCertifiedResource = updateLastCertifiedComponent(component, majorVersion); + if (!updateLastCertifiedResource.equals(StorageOperationStatus.OK)) { + return Either.right(updateLastCertifiedResource); + } + } + + // clone the resource + Either createResourceResult = Either + .right(StorageOperationStatus.GENERAL_ERROR); + switch (nodeType) { + case Service: + case Resource: + createResourceResult = cloneComponentForCertified(component, modifier, majorVersion); + break; + default: + log.error("component object is with type {} . It's not supported type"); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + if (createResourceResult.isRight()) { + log.error("failed to create new resource version for checkout."); + result = createResourceResult; + return createResourceResult; + } + + Component certifiedResource = createResourceResult.left().value(); + + // add rfc relation to preserve follower information + StorageOperationStatus addRfcRelation = addRfcRelationToCertfiedComponent(nodeType, resourceIdBeforeCertify, + certifiedResource.getUniqueId()); + if (!addRfcRelation.equals(StorageOperationStatus.OK)) { + result = Either.right(addRfcRelation); + return result; + } + + result = Either.left(certifiedResource); + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + return result; + } + + @Override + public Either deleteOldComponentVersions(NodeTypeEnum nodeType, + String componentName, String uuid, boolean inTransaction) { + + Either result = null; + ComponentOperation componentOperation = getComponentOperation(nodeType); + + try { + Either, StorageOperationStatus> oldVersionsToDelete = getComponentTempVersions(nodeType, + uuid); + + if (oldVersionsToDelete.isRight()) { + result = Either.right(oldVersionsToDelete.right().value()); + return result; + } + + for (Component resourceToDelete : oldVersionsToDelete.left().value()) { + + Either updateResource = componentOperation + .markComponentToDelete(resourceToDelete, inTransaction); + if (updateResource.isRight()) { + result = Either.right(updateResource.right().value()); + return result; + } + } + result = Either.left(true); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus addRfcRelationToCertfiedComponent(NodeTypeEnum componentType, + String resourceIdBeforeCertify, String uniqueId) { + + // get user of certification request + UniqueIdData componentV = new UniqueIdData(componentType, resourceIdBeforeCertify); + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either rfcRelationResponse = titanGenericDao + .getIncomingRelationByCriteria(componentV, GraphEdgeLabels.LAST_STATE, props); + if (rfcRelationResponse.isRight()) { + TitanOperationStatus status = rfcRelationResponse.right().value(); + log.error("failed to find rfc relation for component {}. status=", resourceIdBeforeCertify, status); + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + GraphRelation rfcRelation = rfcRelationResponse.left().value(); + rfcRelation.setTo( + new RelationEndPoint(componentType, GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId)); + + Either createRelationResponse = titanGenericDao + .createRelation(rfcRelation); + if (createRelationResponse.isRight()) { + TitanOperationStatus status = createRelationResponse.right().value(); + log.error("failed to create rfc relation for component {}. status=", uniqueId, status); + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus updateLastCertifiedComponent(Component component, Integer majorVersion) { + + NodeTypeEnum nodeType = component.getComponentType().getNodeType(); + ComponentOperation componentOperation = getComponentOperation(nodeType); + Map additionalQueryParams = null; + if (nodeType == NodeTypeEnum.Resource) { + ResourceTypeEnum resourceType = ((Resource) component).getResourceType(); + additionalQueryParams = new HashMap(); + additionalQueryParams.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), resourceType.name()); + } + Either getLastCertifiedResponse = componentOperation + .getComponentByNameAndVersion(component.getName(), majorVersion + VERSION_DELIMETER + "0", + additionalQueryParams, true); + + if (getLastCertifiedResponse.isRight()) { + log.error("failed to update last certified resource. status={}", getLastCertifiedResponse.right().value()); + return getLastCertifiedResponse.right().value(); + } + + Component lastCertified = getLastCertifiedResponse.left().value(); + lastCertified.setHighestVersion(false); + Either updateResource = componentOperation.updateComponent(lastCertified, + true); + if (updateResource.isRight()) { + log.error("failed to update last certified resource. status={}", updateResource.right().value()); + return updateResource.right().value(); + } + return StorageOperationStatus.OK; + } + + private Either cloneComponentForCheckout(Component component, + NodeTypeEnum nodeType, User modifier) { + + ComponentOperation componentOperation = getComponentOperation(nodeType); + String prevId = component.getUniqueId(); + // set new version + Either nextVersion = getNextVersion(component.getVersion()); + if (nextVersion.isRight()) { + return Either.right(nextVersion.right().value()); + } + + // if checkout on certified service - init distribution status back + if (nodeType == NodeTypeEnum.Service && component.getLifecycleState().equals(LifecycleStateEnum.CERTIFIED)) { + ((Service) component).setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + } + + String version = nextVersion.left().value(); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + component.setLastUpdateDate(null); + component.setLastUpdaterUserId(modifier.getUserId()); + component.setHighestVersion(true); + + // check version of resource does not exist. Note that resource type VF + // can have same name as resource type VFC + Map additionalQueryParams = null; + if (nodeType == NodeTypeEnum.Resource) { + ResourceTypeEnum resourceType = ((Resource) component).getResourceType(); + additionalQueryParams = new HashMap(); + additionalQueryParams.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), resourceType.name()); + } + String name = component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(); + Either alreadyExistResult = componentOperation + .getComponentByNameAndVersion(name, version, additionalQueryParams, true); + if (alreadyExistResult.isLeft()) { + log.debug("Component with name {} and version {} already exist", name, version); + return Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS); + + } + + StorageOperationStatus storageOperationStatus = alreadyExistResult.right().value(); + if (storageOperationStatus != StorageOperationStatus.NOT_FOUND) { + log.debug( + "Unexpected error when checking if component with name {} and version {} already exist, error: {}", + name, version, storageOperationStatus); + return Either.right(storageOperationStatus); + } + + Either cloneComponentResponse = componentOperation.cloneComponent(component, + version, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, true); + + return cloneComponentResponse; + } + + private Either getNextVersion(String currVersion) { + String[] versionParts = currVersion.split(VERSION_DELIMETER_REGEXP); + if (versionParts == null || versionParts.length != 2) { + log.error("invalid version {}", currVersion); + return Either.right(StorageOperationStatus.BAD_REQUEST); + } + + Integer minorVersion = Integer.parseInt(versionParts[1]) + 1; + String newVersion = versionParts[0] + VERSION_DELIMETER + minorVersion; + return Either.left(newVersion); + } + + private StorageOperationStatus setRelationForCancelCertification(LifecycleStateEnum nextState, + NodeTypeEnum componentType, String componentId) { + + StorageOperationStatus result = StorageOperationStatus.GENERAL_ERROR; + Map props = new HashMap(); + UniqueIdData componentData = new UniqueIdData(componentType, componentId); + + // delete relation CERTIFICATION_IN_PROGRESS + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + Either deleteResult = titanGenericDao + .deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.STATE, props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + + // delete relation READY_FOR_CERTIFICATION (LAST_STATE) + props.put(GraphPropertiesDictionary.STATE.getProperty(), nextState); + + deleteResult = titanGenericDao.deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.LAST_STATE, + props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + GraphRelation origRelation = deleteResult.left().value(); + + // create relation READY_FOR_CERTIFICATION (STATE) + UserData user = new UserData(); + user.setUserId((String) origRelation.getFrom().getIdValue()); + Either createRelationResult = titanGenericDao.createRelation(user, + componentData, GraphEdgeLabels.STATE, origRelation.toGraphMap()); + + if (createRelationResult.isRight()) { + log.error("failed to update last state relation. status={}", createRelationResult.right().value()); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus setRelationForFailCertification(LifecycleStateEnum nextState, + NodeTypeEnum componentType, String componentId) { + + StorageOperationStatus result = null; + Map props = new HashMap(); + UniqueIdData componentData = new UniqueIdData(componentType, componentId); + + // delete relation CERTIFICATION_IN_PROGRESS + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + Either deleteResult = titanGenericDao + .deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.STATE, props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + + // delete relation READY_FOR_CERTIFICATION + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + + deleteResult = titanGenericDao.deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.LAST_STATE, + props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + + // delete relation NOT_CERTIFIED_CHECKIN (in order to change to STATE) + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + deleteResult = titanGenericDao.deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.LAST_STATE, + props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + + // create new STATE relation NOT_CERTIFIED_CHECKIN + GraphRelation origRelation = deleteResult.left().value(); + UserData user = new UserData(); + user.setUserId((String) origRelation.getFrom().getIdValue()); + Either createRelationResult = titanGenericDao.createRelation(user, + componentData, GraphEdgeLabels.STATE, origRelation.toGraphMap()); + + if (createRelationResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + return StorageOperationStatus.OK; + } + + /** + * update service metadata - lastUpdater and state + * + * @param component + * @param modifier + * @param nextState + * @return + */ + private Either updateComponentMD(Component component, User modifier, + LifecycleStateEnum nextState, NodeTypeEnum nodeType, + ComponentParametersView returnedComponentParametersViewFilter) { + + if (returnedComponentParametersViewFilter == null) { + returnedComponentParametersViewFilter = new ComponentParametersView(); + } + + Either result = Either.right(StorageOperationStatus.GENERAL_ERROR); + component.setLastUpdateDate(null); + component.setLastUpdaterUserId(modifier.getUserId()); + + ComponentOperation componentOperation = getComponentOperation(nodeType); + ComponentParametersView filterParametersView = buildFilterForFetchComponentAfterChangeState(); + log.debug("updateComponentMD::updateComponentFilterResult start"); + result = componentOperation.updateComponentFilterResult(component, true, filterParametersView); + log.debug("updateComponentMD::updateComponentFilterResult end"); + if (result.isRight()) { + log.debug("Failed to update component for certification request, error: {}", result.right().value()); + return result; + } + log.debug("updateComponentMD::getAndUpdateMetadata start"); + // get service MD + Either componentDataResult = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(nodeType), component.getUniqueId(), ComponentMetadataData.class); + if (componentDataResult.isRight()) { + log.debug("failed to get service data from graph"); + return Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(componentDataResult.right().value())); + } + + // set state on resource + ComponentMetadataData componentData = componentDataResult.left().value(); + componentData.getMetadataDataDefinition().setState(nextState.name()); + component.setLifecycleState(nextState); + Either updateNode = titanGenericDao.updateNode(componentData, + ComponentMetadataData.class); + log.debug("updateComponentMD::getAndUpdateMetadata end"); + if (updateNode.isRight()) { + log.error("Failed to update component " + component.getUniqueId() + ". status is " + + updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + log.debug("updateComponentMD::getAndUpdateMetadata start"); + Either serviceAfterChange = componentOperation + .getComponent(component.getUniqueId(), returnedComponentParametersViewFilter, true); + log.debug("updateComponentMD::getAndUpdateMetadata end"); + if (serviceAfterChange.isRight()) { + log.error("Failed to get component " + component.getUniqueId() + " after change. status is " + + updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + return Either.left((Component) serviceAfterChange.left().value()); + } + + /** + * update resouce metadata - lastUpdater and state + * + * @param resource + * @param modifier + * @param nextState + * @return + */ + private Either updateResourceMD(Resource resource, User modifier, + LifecycleStateEnum nextState) { + + Either result; + resource.setLastUpdateDate(null); + resource.setLastUpdaterUserId(modifier.getUserId()); + + result = resourceOperation.updateResource(resource, true); + if (result.isRight()) { + log.debug("failed to update resource for certification request."); + return result; + } + // get resource MD + Either resourceDataResult = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resource.getUniqueId(), + ResourceMetadataData.class); + if (resourceDataResult.isRight()) { + log.debug("failed to get resource data from graph"); + return Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceDataResult.right().value())); + } + + // set state on resource + ResourceMetadataData resourceData = resourceDataResult.left().value(); + resourceData.getMetadataDataDefinition().setState(nextState.name()); + resource.setLifecycleState(nextState); + Either updateNode = titanGenericDao.updateNode(resourceData, + ResourceMetadataData.class); + + if (updateNode.isRight()) { + log.error("Failed to update resource " + resource.getUniqueId() + ". status is " + + updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + return Either.left(resource); + } + + private Either, StorageOperationStatus> getComponentTempVersions(NodeTypeEnum nodeType, + String uuid) { + + Either, StorageOperationStatus> result = Either.right(StorageOperationStatus.GENERAL_ERROR); + List componentList = new ArrayList(); + ComponentOperation componentOperation = getComponentOperation(nodeType); + + Map hasProps = new HashMap(); + Map hasNotProps = new HashMap(); + + createOldVersionsCriteria(nodeType, uuid, hasProps, hasNotProps); + + Either, TitanOperationStatus> getByCriteria = titanGenericDao + .getByCriteria(nodeType, hasProps, hasNotProps, ComponentMetadataData.class); + + if (getByCriteria.isRight()) { + log.error("failed to get old versions for component, type:{}, id: {}", nodeType, uuid); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getByCriteria.right().value())); + return result; + } + + List oldVersionComponents = getByCriteria.left().value(); + for (ComponentMetadataData component : oldVersionComponents) { + Either resourceRes = componentOperation + .getComponent(component.getMetadataDataDefinition().getUniqueId(), true); + if (resourceRes.isRight()) { + result = Either.right(resourceRes.right().value()); + return result; + } else { + componentList.add(resourceRes.left().value()); + } + } + result = Either.left(componentList); + return result; + } + + private void createOldVersionsCriteria(NodeTypeEnum nodeType, String uuid, Map hasProps, + Map hasNotProps) { + + hasProps.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + hasProps.put(GraphPropertiesDictionary.LABEL.getProperty(), nodeType.name().toLowerCase()); + hasNotProps.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + } + + private Either updateOldComponentBeforeUndoCheckout( + ComponentOperation componentOperation, Component prevComponent, Component currentComponent, + String previousVersion, NodeTypeEnum nodeType, boolean inTransaction) { + + log.debug("update previous version of component"); + Map additionalQueryParams = new HashMap(); + + if (nodeType == NodeTypeEnum.Resource) { + ResourceTypeEnum resourceType = ((Resource) currentComponent).getResourceType(); + + additionalQueryParams.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), resourceType.name()); + } + ComponentMetadataDataDefinition metadataDataDefinition = currentComponent.getComponentMetadataDefinition() + .getMetadataDataDefinition(); + Either getOlderCompResult = componentOperation + .getComponentByNameAndVersion(metadataDataDefinition.getName(), previousVersion, additionalQueryParams, + true); + + // if previous version exist - set it as current version + if (getOlderCompResult.isRight()) { + if (StorageOperationStatus.NOT_FOUND.equals(getOlderCompResult.right().value())) { + log.debug("No components by name and version : {} {}", metadataDataDefinition.getName(), previousVersion); + log.debug("Name may have changed, since the version isn't certified try to fetch by UUID {}", metadataDataDefinition.getUUID()); + additionalQueryParams.clear(); + additionalQueryParams.put(GraphPropertiesDictionary.UUID.getProperty(), + metadataDataDefinition.getUUID()); + additionalQueryParams.put(GraphPropertiesDictionary.VERSION.getProperty(), previousVersion); + + Either, TitanOperationStatus> byUUID = titanGenericDao + .getByCriteria(nodeType, additionalQueryParams, ComponentMetadataData.class); + if (byUUID.isRight()) { + log.debug("Failed to fetch by UUID {}", metadataDataDefinition.getUUID()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byUUID.right().value())); + } + String prevVersionId = (String) byUUID.left().value().get(0).getUniqueId(); + Either component = componentOperation + .getComponent(prevVersionId, inTransaction); + if (component.isRight()) { + log.debug("Failed to fetch previous component by ID {}", prevVersionId); + return Either.right(component.right().value()); + } + prevComponent = component.left().value(); + } else { + log.error("failed to find previous version. status={} ", getOlderCompResult.right().value()); + return getOlderCompResult; + } + } else { + prevComponent = getOlderCompResult.left().value(); + } + + // if last resource is certified - don't touch it. + if (prevComponent.getVersion().endsWith(".0")) { + return Either.left(prevComponent); + } + + prevComponent.setHighestVersion(true); + Either updateCompResult = componentOperation.updateComponent(prevComponent, + inTransaction); + if (updateCompResult.isRight()) { + log.debug("failed to update prev version of component"); + return updateCompResult; + } + + User user = new User(); + user.setUserId(prevComponent.getLastUpdaterUserId()); + StorageOperationStatus changeStateRelation = changeStateRelation(nodeType, prevComponent.getUniqueId(), user, + GraphEdgeLabels.LAST_STATE, GraphEdgeLabels.STATE); + if (!changeStateRelation.equals(StorageOperationStatus.OK)) { + return Either.right(changeStateRelation); + } + + return Either.left(prevComponent); + } + + private StorageOperationStatus changeStateRelation(NodeTypeEnum nodeType, String componentId, User currentOwner, + GraphEdgeLabels from, GraphEdgeLabels to) { + UniqueIdData componentData = new UniqueIdData(nodeType, componentId); + UserData userData = new UserData(); + userData.setUserId(currentOwner.getUserId()); + Either replaceRelationLabelResult = titanGenericDao + .replaceRelationLabel(userData, componentData, from, to); + if (replaceRelationLabelResult.isRight()) { + TitanOperationStatus titanStatus = replaceRelationLabelResult.right().value(); + log.error("failed to replace label from {} to {}. status = {}", from, to, titanStatus); + StorageOperationStatus storageStatus = StorageOperationStatus.INCONSISTENCY; + if (!titanStatus.equals(TitanOperationStatus.INVALID_ID)) { + storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + return storageStatus; + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus removeUserToResourceRelation(NodeTypeEnum componentType, String idFrom, String idTo, + GraphEdgeLabels label) { + + UniqueIdData componentV = new UniqueIdData(componentType, idTo); + UserData userV = new UserData(); + userV.setUserId(idFrom); + // delete relation + Either deleteRelationResult = titanGenericDao.deleteRelation(userV, + componentV, label); + if (deleteRelationResult.isRight()) { + log.error("failed to delete relation. status={}", deleteRelationResult.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteRelationResult.right().value()); + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus createUserToResourceRelation(NodeTypeEnum componentType, String idFrom, String idTo, + GraphEdgeLabels label, Map props) { + + UniqueIdData componentV = new UniqueIdData(componentType, idTo); + UserData userV = new UserData(); + userV.setUserId(idFrom); + // create relation + Either createRelationResult = titanGenericDao.createRelation(userV, + componentV, label, props); + if (createRelationResult.isRight()) { + log.error("failed to create relation. status={}", createRelationResult.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(createRelationResult.right().value()); + } + return StorageOperationStatus.OK; + } + + @Override + public Either cancelOrFailCertification(NodeTypeEnum nodeType, + Component component, User modifier, User owner, LifecycleStateEnum nextState, boolean inTransaction) { + + Either result = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + + ComponentParametersView componentParametersView = buildFilterForFetchComponentAfterChangeState(); + result = updateComponentMD(component, modifier, nextState, nodeType, componentParametersView); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + nextState, result.right().value()); + return result; + } + StorageOperationStatus status = StorageOperationStatus.OK; + // cancel certification process + if (nextState.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION)) { + status = setRelationForCancelCertification(nextState, nodeType, component.getUniqueId()); + + } // fail certification + else if (nextState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN)) { + status = setRelationForFailCertification(nextState, nodeType, component.getUniqueId()); + } + + if (!status.equals(StorageOperationStatus.OK)) { + result = Either.right(status); + } + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + return result; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java new file mode 100644 index 0000000000..55531fec79 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.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.be.model.operations.impl; + +import org.openecomp.sdc.be.dao.neo4j.Neo4jOperationStatus; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; + +public class Neo4jStatusConverter { + + public static StorageOperationStatus convertNeo4jStatusToStorageStatus(Neo4jOperationStatus neo4jStatus) { + + if (neo4jStatus == null) { + return StorageOperationStatus.GENERAL_ERROR; + } + + switch (neo4jStatus) { + + case OK: + return StorageOperationStatus.OK; + + case NOT_CONNECTED: + return StorageOperationStatus.CONNECTION_FAILURE; + + case NOT_AUTHORIZED: + return StorageOperationStatus.PERMISSION_ERROR; + + case HTTP_PROTOCOL_ERROR: + return StorageOperationStatus.HTTP_PROTOCOL_ERROR; + case DB_NOT_AVAILABLE: + return StorageOperationStatus.STORAGE_NOT_AVAILABLE; + case DB_READ_ONLY: + return StorageOperationStatus.READ_ONLY_STORAGE; + case BAD_REQUEST: + return StorageOperationStatus.BAD_REQUEST; + case LEGACY_INDEX_ERROR: + return StorageOperationStatus.STORAGE_LEGACY_INDEX_ERROR; + case SCHEMA_ERROR: + return StorageOperationStatus.SCHEMA_ERROR; + case TRANSACTION_ERROR: + return StorageOperationStatus.TRANSACTION_ERROR; + case EXECUTION_FAILED: + return StorageOperationStatus.EXEUCTION_FAILED; + case ENTITY_ALREADY_EXIST: + return StorageOperationStatus.ENTITY_ALREADY_EXISTS; + case WRONG_INPUT: + return StorageOperationStatus.BAD_REQUEST; + case GENERAL_ERROR: + return StorageOperationStatus.GENERAL_ERROR; + case NOT_SUPPORTED: + return StorageOperationStatus.OPERATION_NOT_SUPPORTED; + case NOT_FOUND: + return StorageOperationStatus.NOT_FOUND; + + default: + return StorageOperationStatus.GENERAL_ERROR; + } + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java new file mode 100644 index 0000000000..a7f8275064 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java @@ -0,0 +1,190 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Map; +import java.util.Properties; + +import javax.annotation.PostConstruct; + +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.apache.http.HttpStatus; +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.config.Configuration.OnboardingConfig; +import org.openecomp.sdc.be.dao.rest.HttpRestClient; +import org.openecomp.sdc.be.dao.rest.RestConfigurationInfo; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.rest.api.RestResponseAsByteArray; +import org.openecomp.sdc.common.util.ZipUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("onboarding-client") +public class OnboardingClient { + + private static Logger log = LoggerFactory.getLogger(OnboardingClient.class.getName()); + + private HttpRestClient httpRestClient = null; + + private static Properties downloadCsarHeaders = new Properties(); + + static { + downloadCsarHeaders.put("Accept", "application/octet-stream"); + } + + public OnboardingClient() { + super(); + } + + public static void main(String[] args) { + + OnboardingClient csarOperation = new OnboardingClient(); + csarOperation.init(); + + String csarUuid = "70025CF6081B489CA7B1CBA583D5278D"; + Either, StorageOperationStatus> csar = csarOperation.getCsar(csarUuid, null); + System.out.println(csar.left().value()); + + } + + @PostConstruct + public void init() { + + // TODO: read connection configuration from OnboardingConfig + // onboardingConfig = + // ConfigurationManager.getConfigurationManager().getConfiguration().getOnboarding(); + + RestConfigurationInfo restConfigurationInfo = new RestConfigurationInfo(); + httpRestClient = new HttpRestClient(restConfigurationInfo); + + if (false == httpRestClient.isInitialized()) { + BeEcompErrorManager.getInstance().logInternalFlowError("InitializeRestClient", "Failed to initialize rest client", ErrorSeverity.FATAL); + httpRestClient = null; + } + + } + + // Mock returning a file from the file system until we have API from onboarding + public Either, StorageOperationStatus> getMockCsar(String csarUuid) { + File dir = new File("/var/tmp/mockCsar"); + FileFilter fileFilter = new WildcardFileFilter("*.csar"); + File[] files = dir.listFiles(fileFilter); + for (int i = 0; i < files.length; i++) { + File csar = files[i]; + if (csar.getName().startsWith(csarUuid)) { + log.debug("Found CSAR file {} matching the passed csarUuid {}", csar.getAbsolutePath(), csarUuid); + byte[] data; + try { + data = Files.readAllBytes(csar.toPath()); + } catch (IOException e) { + log.debug("Error reading mock file for CSAR, error: {}", e); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Map readZip = ZipUtil.readZip(data); + return Either.left(readZip); + } + } + log.debug("Couldn't find mock file for CSAR starting with {}", csarUuid); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + public Either, StorageOperationStatus> getCsar(String csarUuid, String userId) { + + if (httpRestClient == null) { + BeEcompErrorManager.getInstance().logInternalFlowError("RestClient", "Rest Client could not be initialized", ErrorSeverity.ERROR); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + String url = buildDownloadCsarUrl() + "/" + csarUuid; + + Properties headers = new Properties(); + if (downloadCsarHeaders != null) { + downloadCsarHeaders.forEach((k, v) -> headers.put(k, v)); + } + + if (userId != null) { + headers.put(Constants.USER_ID_HEADER, userId); + } + + log.debug("Url for downloading csar is {}. Headers are {}", url, headers); + + RestResponseAsByteArray restResponse = httpRestClient.doGetAsByteArray(url, headers); + log.debug("After fetching csar {}. Http return code is {}", csarUuid, restResponse.getHttpStatusCode()); + + switch (restResponse.getHttpStatusCode()) { + case HttpStatus.SC_OK: + byte[] data = restResponse.getResponse(); + if (data != null && data.length > 0) { + Map readZip = ZipUtil.readZip(data); + return Either.left(readZip); + } else { + log.debug("Data received from rest is null or empty"); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + case HttpStatus.SC_NOT_FOUND: + return Either.right(StorageOperationStatus.CSAR_NOT_FOUND); + + default: + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + } + + public HttpRestClient getHttpRestClient() { + return httpRestClient; + } + + public void setHttpRestClient(HttpRestClient httpRestClient) { + this.httpRestClient = httpRestClient; + } + + /** + * Build the url for download CSAR + * + * E.g., http://1.2.3.4:8181/onboarding-api/v1.0/vendor-software-products/packages/ + * + * @return + */ + public String buildDownloadCsarUrl() { + + OnboardingConfig onboardingConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getOnboarding(); + + String protocol = onboardingConfig.getProtocol(); + String host = onboardingConfig.getHost(); + Integer port = onboardingConfig.getPort(); + String uri = onboardingConfig.getDownloadCsarUri(); + + String getCsarUrl = protocol + "://" + host + ":" + port + uri; + + return getCsarUrl; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java new file mode 100644 index 0000000000..d085c242e8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.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.model.operations.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import javax.annotation.Resource; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.IPolicyTypeOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.PolicyTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("policy-type-operation") +public class PolicyTypeOperation extends AbstractOperation implements IPolicyTypeOperation { + + private static final String CREATE_FLOW_CONTEXT = "CreatePolicyType"; + private static final String GET_FLOW_CONTEXT = "GetPolicyType"; + + @Resource + private PropertyOperation propertyOperation; + + public PolicyTypeOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(PolicyTypeOperation.class.getName()); + + @Override + public Either getLatestPolicyTypeByType(String policyTypeName) { + return getLatestPolicyTypeByType(policyTypeName, false); + } + + private Either getLatestPolicyTypeByType(String type, + boolean inTransaction) { + Map mapCriteria = new HashMap<>(); + mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); + mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + return getPolicyTypeByCriteria(type, mapCriteria, inTransaction); + } + + @Override + public Either addPolicyType(PolicyTypeDefinition policyType) { + return addPolicyType(policyType, false); + } + + @Override + public Either addPolicyType(PolicyTypeDefinition policyTypeDef, + boolean inTransaction) { + + Either result = null; + + try { + + Either eitherStatus = addPolicyTypeToGraph(policyTypeDef); + + if (eitherStatus.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, + policyTypeDef.getType(), eitherStatus.right().value().name()); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + + } else { + PolicyTypeData policyTypeData = eitherStatus.left().value(); + + String uniqueId = policyTypeData.getUniqueId(); + Either policyTypeRes = this.getPolicyType(uniqueId, true); + + if (policyTypeRes.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, + policyTypeDef.getType(), eitherStatus.right().value().name()); + } + + result = policyTypeRes; + + } + + return result; + + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + + } + + private Either addPolicyTypeToGraph(PolicyTypeDefinition policyTypeDef) { + log.debug("Got policy type {}", policyTypeDef); + + String ptUniqueId = UniqueIdBuilder.buildPolicyTypeUid(policyTypeDef.getType(), policyTypeDef.getVersion()); + + PolicyTypeData policyTypeData = buildPolicyTypeData(policyTypeDef, ptUniqueId); + + log.debug("Before adding policy type to graph. policyTypeData = {}", policyTypeData); + + Either eitherPolicyTypeData = titanGenericDao.createNode(policyTypeData, + PolicyTypeData.class); + log.debug("After adding policy type to graph. status is = {}", eitherPolicyTypeData); + + if (eitherPolicyTypeData.isRight()) { + TitanOperationStatus operationStatus = eitherPolicyTypeData.right().value(); + log.error("Failed to add policy type {} to graph. Status is {}", policyTypeDef.getType(), operationStatus); + return Either.right(operationStatus); + } + + PolicyTypeData resultCTD = eitherPolicyTypeData.left().value(); + List properties = policyTypeDef.getProperties(); + Either, TitanOperationStatus> addPropertiesToPolicyType = propertyOperation + .addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.PolicyType, properties); + if (addPropertiesToPolicyType.isRight()) { + log.error("Failed add properties {} to policy {}", properties, policyTypeDef.getType()); + return Either.right(addPropertiesToPolicyType.right().value()); + } + + return Either.left(eitherPolicyTypeData.left().value()); + } + + public Either getPolicyTypeByCriteria(String type, + Map properties, boolean inTransaction) { + Either result = null; + try { + if (type == null || type.isEmpty()) { + log.error("type is empty"); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + Either, TitanOperationStatus> eitherPolicyData = titanGenericDao + .getByCriteria(NodeTypeEnum.PolicyType, properties, PolicyTypeData.class); + if (eitherPolicyData.isRight()) { + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherPolicyData.right().value())); + } else { + PolicyTypeDataDefinition dataDefinition = eitherPolicyData.left().value().stream() + .map(e -> e.getPolicyTypeDataDefinition()).findFirst().get(); + result = getPolicyType(dataDefinition.getUniqueId(), inTransaction); + } + + return result; + + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + } + + @Override + public Either getPolicyType(String uniqueId, boolean inTransaction) { + Function> policyTypeGetter = uId -> getPolicyTypeByUid( + uId); + return getElementType(policyTypeGetter, uniqueId, inTransaction); + + } + + private Either getPolicyTypeByUid(String uniqueId) { + Either result = null; + + Either eitherPolicyTypeData = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PolicyType), uniqueId, PolicyTypeData.class); + + if (eitherPolicyTypeData.isRight()) { + TitanOperationStatus status = eitherPolicyTypeData.right().value(); + log.debug("Policy type {} cannot be found in graph. Status is {}", uniqueId, status); + return Either.right(status); + } + + PolicyTypeData policyTypeData = eitherPolicyTypeData.left().value(); + PolicyTypeDefinition policyTypeDefinition = new PolicyTypeDefinition( + policyTypeData.getPolicyTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = propertyOperation.fillProperties(uniqueId, + propList -> policyTypeDefinition.setProperties(propList)); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of policy type {}", uniqueId); + return Either.right(propertiesStatus); + } + + result = Either.left(policyTypeDefinition); + + return result; + } + + private PolicyTypeData buildPolicyTypeData(PolicyTypeDefinition policyTypeDefinition, String ptUniqueId) { + + PolicyTypeData policyTypeData = new PolicyTypeData(policyTypeDefinition); + + policyTypeData.getPolicyTypeDataDefinition().setUniqueId(ptUniqueId); + Long creationDate = policyTypeData.getPolicyTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + + policyTypeData.getPolicyTypeDataDefinition().setCreationTime(creationDate); + policyTypeData.getPolicyTypeDataDefinition().setModificationTime(creationDate); + return policyTypeData; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ProductOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ProductOperation.java new file mode 100644 index 0000000000..2a8192421b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ProductOperation.java @@ -0,0 +1,1067 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.Set; + +import com.thinkaurelius.titan.core.TitanTransaction; +import org.apache.commons.lang3.tuple.ImmutablePair; +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.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; +import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ProductMetadataDataDefinition; +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.model.*; +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.IProductOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ProductMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.GroupingData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.thinkaurelius.titan.core.TitanGraph; + +import fj.data.Either; + +@org.springframework.stereotype.Component("product-operation") +public class ProductOperation extends ComponentOperation implements IProductOperation { + + private static Logger log = LoggerFactory.getLogger(ProductOperation.class.getName()); + + public ProductOperation() { + log.debug("ProductOperation created"); + } + + @Override + protected ComponentMetadataData getMetaDataFromComponent(Component component) { + return getProductMetadataDataFromProduct((Product) component); + } + + @SuppressWarnings("unchecked") + @Override + public Either getComponent(String id, boolean inTransaction) { + return (Either) getProduct(id, inTransaction); + } + + // public Either getComponent_tx(String id, + // boolean inTransaction) { + // return (Either) getProduct_tx(id, + // inTransaction); + // } + + @SuppressWarnings("unchecked") + @Override + protected Either getComponentByNameAndVersion(String name, String version, + Map additionalParams, boolean inTransaction) { + return (Either) getByNamesAndVersion(GraphPropertiesDictionary.NAME.getProperty(), + name, version, additionalParams, inTransaction); + } + + @Override + public Either getLightComponent(String id, boolean inTransaction) { + return getLightComponent(id, NodeTypeEnum.Product, inTransaction); + } + + @Override + public Either, StorageOperationStatus> getFilteredComponents(Map filters, + boolean inTransaction) { + return getFilteredComponents(filters, inTransaction, NodeTypeEnum.Product); + } + + private Product convertProductDataToProduct(ProductMetadataData productData) { + ProductMetadataDefinition productMetadataDefinition = new ProductMetadataDefinition( + (ProductMetadataDataDefinition) productData.getMetadataDataDefinition()); + + Product product = new Product(productMetadataDefinition); + + return product; + } + + @SuppressWarnings("unchecked") + @Override + public Either updateComponent(T component, boolean inTransaction) { + return (Either) updateComponent((Component) component, inTransaction, + titanGenericDao, Product.class, NodeTypeEnum.Product); + } + + @SuppressWarnings("unchecked") + @Override + public Either deleteComponent(String id, boolean inTransaction) { + return (Either) (Either) deleteProduct(id, + inTransaction); + } + + @Override + public Either, StorageOperationStatus> getAdditionalArtifacts(String resourceId, + boolean recursively, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + @Override + public Either getComponent(String id, + Class clazz) { + return (Either) getProduct(id, false); + } + + @Override + /** + * Deletes the product node + */ + public Either deleteProduct(String productId, boolean inTransaction) { + + Either result = Either.right(StorageOperationStatus.GENERAL_ERROR); + + try { + + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + + Either productNode = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Product), productId, ProductMetadataData.class); + if (productNode.isRight()) { + TitanOperationStatus status = productNode.right().value(); + log.error("Failed to find product {}. Status is {}", productId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Either productRes = getProduct(productId, true); + if (productRes.isRight()) { + StorageOperationStatus status = productRes.right().value(); + log.error("Failed to find product {}", productId, status); + result = Either.right(status); + return result; + } + Product product = productRes.left().value(); + + Either, StorageOperationStatus> deleteAllInstancesRes = componentInstanceOperation + .deleteAllComponentInstances(productId, NodeTypeEnum.Product, true); + log.debug("After deleting instances under product {}. Result is {}", productId, deleteAllInstancesRes); + if (deleteAllInstancesRes.isRight()) { + StorageOperationStatus status = deleteAllInstancesRes.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + log.error("Failed to delete instances under product {}. Status is {}", productId, status); + result = Either.right(status); + return result; + } + } + + Either deleteProductNodeRes = titanGenericDao + .deleteNode(productNode.left().value(), ProductMetadataData.class); + if (deleteProductNodeRes.isRight()) { + TitanOperationStatus status = deleteProductNodeRes.right().value(); + log.error("Failed to delete product node {}. Status is {}", productId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + result = Either.left(product); + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("deleteProduct operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("deleteProduct operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either, StorageOperationStatus> getProductCatalogData(boolean inTransaction) { + + long start = System.currentTimeMillis(); + try { + /* + * Map propertiesToMatch = new HashMap<>(); + * + * propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty + * (), LifecycleStateEnum.CERTIFIED.name()); + * Either, TitanOperationStatus> + * lastVersionNodes = getLastVersion(NodeTypeEnum.Product, + * propertiesToMatch, ProductMetadataData.class); if + * (lastVersionNodes.isRight() && lastVersionNodes.right().value() + * != TitanOperationStatus.NOT_FOUND) { return + * Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus + * (lastVersionNodes.right().value())); } List + * notCertifiedHighest = (lastVersionNodes.isLeft() ? + * lastVersionNodes.left().value() : new + * ArrayList()); + * + * propertiesToMatch.put(GraphPropertiesDictionary. + * IS_HIGHEST_VERSION.getProperty(), true); + * Either, TitanOperationStatus> + * componentsNodes = + * titanGenericDao.getByCriteria(NodeTypeEnum.Product, + * propertiesToMatch, ProductMetadataData.class); if + * (componentsNodes.isRight() && componentsNodes.right().value() != + * TitanOperationStatus.NOT_FOUND) { return + * Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus + * (componentsNodes.right().value())); } List + * certifiedHighest = (componentsNodes.isLeft() ? + * componentsNodes.left().value() : new + * ArrayList()); Set names = new + * HashSet(); for (ProductMetadataData data : + * notCertifiedHighest) { String name = + * data.getMetadataDataDefinition().getName(); names.add(name); } + * + * for (ProductMetadataData data : certifiedHighest) { String + * productName = data.getMetadataDataDefinition().getName(); if + * (!names.contains(productName)) { notCertifiedHighest.add(data); } + * } + */ + Either, TitanOperationStatus> listOfHighestComponents = this + .getListOfHighestComponents(NodeTypeEnum.Product, ProductMetadataData.class); + if (listOfHighestComponents.isRight() + && listOfHighestComponents.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(listOfHighestComponents.right().value())); + } + + List notCertifiedHighest = listOfHighestComponents.left().value(); + + List result = new ArrayList<>(); + + if (notCertifiedHighest != null && false == notCertifiedHighest.isEmpty()) { + + // fetch from cache + long startFetchAllFromCache = System.currentTimeMillis(); + + Map components = notCertifiedHighest.stream() + .collect(Collectors.toMap(p -> p.getMetadataDataDefinition().getUniqueId(), + p -> p.getMetadataDataDefinition().getLastUpdateDate())); + + Either, Set>, ActionStatus> componentsFromCacheForCatalog = this + .getComponentsFromCacheForCatalog(components, ComponentTypeEnum.PRODUCT); + if (componentsFromCacheForCatalog.isLeft()) { + ImmutablePair, Set> immutablePair = componentsFromCacheForCatalog.left() + .value(); + List list = immutablePair.getLeft(); + if (list != null) { + for (Component component : list) { + result.add((Product) component); + } + List addedUids = list.stream() + .map(p -> p.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId()) + .collect(Collectors.toList()); + notCertifiedHighest = notCertifiedHighest.stream() + .filter(p -> false == addedUids.contains(p.getMetadataDataDefinition().getUniqueId())) + .collect(Collectors.toList()); + } + } + long endFetchAllFromCache = System.currentTimeMillis(); + log.debug("Fetch all catalog products metadata from cache took {} ms", + (endFetchAllFromCache - startFetchAllFromCache)); + log.debug("The number of products added to catalog from cache is {}", result.size()); + + log.debug("The number of products needed to be fetch as light component is {}", + notCertifiedHighest.size()); + + for (ProductMetadataData data : notCertifiedHighest) { + Either component = getLightComponent( + data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get product for id = {}, error : {}. skip product", data.getUniqueId(), + component.right().value()); + } else { + // get all versions + Product product = component.left().value(); + // setAllVersions(product); + + result.add(product); + } + } + } + return Either.left(result); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + log.debug("Fetch all catalog products took {} ms", (System.currentTimeMillis() - start)); + } + } + + @Override + public Either createProduct(Product product) { + return createProduct(product, false); + } + + @Override + public Either createProduct(Product product, boolean inTransaction) { + Either result = null; + + try { + + ProductMetadataData productData = getProductMetadataDataFromProduct(product); + addComponentInternalFields(productData); + String uniqueId = (String) productData.getUniqueId(); + generateUUID(product); + + String userId = product.getCreatorUserId(); + + Either findUser = findUser(userId); + + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user {} in the graph. status is {}", userId, status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } + + UserData creatorUserData = findUser.left().value(); + UserData updaterUserData = creatorUserData; + String updaterUserId = product.getLastUpdaterUserId(); + if (updaterUserId != null && !updaterUserId.equals(userId)) { + findUser = findUser(updaterUserId); + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user {} in the graph. status is {}", userId, status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } else { + updaterUserData = findUser.left().value(); + } + } + + log.trace("Creating tags for product {}", uniqueId); + StorageOperationStatus storageOperationStatus = createTagsForComponent(product); + if (storageOperationStatus != StorageOperationStatus.OK) { + return Either.right(storageOperationStatus); + } + + log.trace("Finding groupings for product {}", uniqueId); + Either, StorageOperationStatus> findGroupingsForComponent = findGroupingsForComponent( + NodeTypeEnum.ProductGrouping, product); + if (findGroupingsForComponent.isRight()) { + return Either.right(findGroupingsForComponent.right().value()); + } + List groupingDataToAssociate = findGroupingsForComponent.left().value(); + + log.debug("try to create product node on graph for id {}", uniqueId); + Either createNode = titanGenericDao.createNode(productData, + ProductMetadataData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Error returned after creating product data node {}. Status returned is {}", productData, + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + log.debug("product node created on graph for id {}", productData.getUniqueId()); + + TitanOperationStatus associateMetadata = associateMetadataToComponent(productData, creatorUserData, + updaterUserData, null, null); + if (associateMetadata != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateMetadata)); + return result; + } + + TitanOperationStatus associateCategories = associateCategoriesToProduct(productData, + groupingDataToAssociate); + if (associateCategories != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateCategories)); + return result; + } + + result = getProduct(uniqueId, true); + if (result.isRight()) { + log.error("Cannot get full product from the graph. status is {}", result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Product retrieved is {}", json); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private TitanOperationStatus associateCategoriesToProduct(ProductMetadataData productData, + List groupingDataToAssociate) { + for (GroupingData groupingData : groupingDataToAssociate) { + GraphEdgeLabels groupingLabel = GraphEdgeLabels.CATEGORIZED_TO; + Either result = titanGenericDao.createRelation(productData, + groupingData, groupingLabel, null); + log.debug("After associating grouping {} to product {}. Edge type is {}", groupingData, productData, + groupingLabel); + if (result.isRight()) { + return result.right().value(); + } + } + log.trace("All groupings associated succesfully to product {}", productData); + return TitanOperationStatus.OK; + } + + private TitanOperationStatus dissociateCategoriesFromProduct(ProductMetadataData productData, + List groupingDataToDissociate) { + for (GroupingData groupingData : groupingDataToDissociate) { + GraphEdgeLabels groupingLabel = GraphEdgeLabels.CATEGORIZED_TO; + Either result = titanGenericDao.deleteRelation(productData, + groupingData, groupingLabel); + log.debug("After dissociating grouping {} from product {}. Edge type is {}", groupingData, productData, + groupingLabel); + if (result.isRight()) { + return result.right().value(); + } + } + log.trace("All groupings dissociated succesfully from product {}", productData); + return TitanOperationStatus.OK; + } + + private Either getProduct(String uniqueId, boolean inTransaction) { + ComponentParametersView componentParametersView = new ComponentParametersView(); + return getProduct(uniqueId, componentParametersView, inTransaction); + } + + private Either getProduct(String uniqueId, + ComponentParametersView componentParametersView, boolean inTransaction) { + Product product = null; + Either result = null; + try { + + NodeTypeEnum productNodeType = NodeTypeEnum.Product; + NodeTypeEnum compInstNodeType = NodeTypeEnum.Service; + + Either getComponentByLabel = getComponentByLabelAndId(uniqueId, + productNodeType, ProductMetadataData.class); + if (getComponentByLabel.isRight()) { + result = Either.right(getComponentByLabel.right().value()); + return result; + } + ProductMetadataData productData = getComponentByLabel.left().value(); + + // Try to fetch resource from the cache. The resource will be + // fetched only if the time on the cache equals to + // the time on the graph. + Either componentFromCacheIfUpToDate = this.getComponentFromCacheIfUpToDate(uniqueId, + productData, componentParametersView, Product.class, ComponentTypeEnum.PRODUCT); + if (componentFromCacheIfUpToDate.isLeft()) { + Product cachedProduct = componentFromCacheIfUpToDate.left().value(); + log.debug("Product {} with uid {} was fetched from cache.", cachedProduct.getName(), + cachedProduct.getUniqueId()); + return Either.left(cachedProduct); + } + + product = convertProductDataToProduct(productData); + + TitanOperationStatus status = null; + if (false == componentParametersView.isIgnoreUsers()) { + status = setComponentCreatorFromGraph(product, uniqueId, productNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + status = setComponentLastModifierFromGraph(product, uniqueId, productNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + if (false == componentParametersView.isIgnoreCategories()) { + status = setComponentCategoriesFromGraph(product); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + if (false == componentParametersView.isIgnoreComponentInstances() + || false == componentParametersView.isIgnoreComponentInstancesProperties() + || false == componentParametersView.isIgnoreCapabilities() + || false == componentParametersView.isIgnoreRequirements()) { + status = setComponentInstancesFromGraph(uniqueId, product, productNodeType, compInstNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + if (false == componentParametersView.isIgnoreComponentInstancesProperties()) { + status = setComponentInstancesPropertiesFromGraph(uniqueId, product); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreCapabilities()) { + status = setCapabilitiesFromGraph(uniqueId, product, NodeTypeEnum.Product); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreRequirements()) { + status = setRequirementsFromGraph(uniqueId, product, NodeTypeEnum.Product); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + if (false == componentParametersView.isIgnoreAllVersions()) { + status = setAllVersions(product); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + result = Either.left(product); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + } + + // private Either getProduct_tx(String + // uniqueId, boolean inTransaction) { + // Product product = null; + // Either result = null; + // try { + // + // NodeTypeEnum productNodeType = NodeTypeEnum.Product; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Service; + // + // Either getComponentByLabel = + // getComponentByLabelAndId_tx(uniqueId, productNodeType, + // ProductMetadataData.class); + // if (getComponentByLabel.isRight()) { + // result = Either.right(getComponentByLabel.right().value()); + // return result; + // } + // ProductMetadataData productData = getComponentByLabel.left().value(); + // product = convertProductDataToProduct(productData); + // + // TitanOperationStatus status = setComponentCreatorFromGraph(product, + // uniqueId, productNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setComponentLastModifierFromGraph(product, uniqueId, + // productNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // status = setComponentCategoriesFromGraph(product); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setComponentInstancesFromGraph(uniqueId, product, + // productNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, product); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setCapabilitiesFromGraph(uniqueId, product, + // NodeTypeEnum.Product); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setRequirementsFromGraph( uniqueId, product, + // NodeTypeEnum.Product);; + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // + // status = setAllVersions(product); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // result = Either.left(product); + // return result; + // + // } finally { + // if (false == inTransaction) { + // if (result == null || result.isRight()) { + // titanGenericDao.rollback(); + // } else { + // titanGenericDao.commit(); + // } + // } + // } + // } + + private TitanOperationStatus setAllVersions(Product product) { + Either, TitanOperationStatus> res = getVersionList(NodeTypeEnum.Product, + product.getVersion(), product, ProductMetadataData.class); + if (res.isRight()) { + return res.right().value(); + } + product.setAllVersions(res.left().value()); + return TitanOperationStatus.OK; + } + + private Either sendError(TitanOperationStatus status, + StorageOperationStatus statusIfNotFound) { + Either result; + if (status == TitanOperationStatus.NOT_FOUND) { + result = Either.right(statusIfNotFound); + return result; + } else { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + @Override + TitanOperationStatus setComponentCategoriesFromGraph(Component component) { + Product product = (Product) component; + // Building the cat->subcat->grouping triples + Either>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Product), product.getUniqueId(), + GraphEdgeLabels.CATEGORIZED_TO, NodeTypeEnum.ProductGrouping, GroupingData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Error when finding groupings for this product, error {}", childrenNodes.right().value()); + return childrenNodes.right().value(); + } else { + log.debug("No groupings found for this product - this might be normal"); + return TitanOperationStatus.OK; + } + } + Map>> categoriesDataStructure = new HashMap<>(); + + List> valueList = childrenNodes.left().value(); + for (ImmutablePair groupPair : valueList) { + GroupingData groupingData = groupPair.getLeft(); + Either, TitanOperationStatus> parentSubCat = titanGenericDao + .getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ProductGrouping), + (String) groupingData.getUniqueId(), GraphEdgeLabels.GROUPING, + NodeTypeEnum.ProductSubcategory, SubCategoryData.class); + if (parentSubCat.isRight()) { + log.debug("Cannot find subcategory for grouping {}", groupingData.getUniqueId()); + return parentSubCat.right().value(); + } + SubCategoryData subCatData = parentSubCat.left().value().getLeft(); + Either, TitanOperationStatus> parentCat = titanGenericDao + .getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ProductSubcategory), + (String) subCatData.getUniqueId(), GraphEdgeLabels.SUB_CATEGORY, + NodeTypeEnum.ProductCategory, CategoryData.class); + if (parentCat.isRight()) { + log.debug("Cannot find category for subcategory {}", subCatData.getUniqueId()); + return parentCat.right().value(); + } + + // Building data structure of categories hierarchy + CategoryDataDefinition categoryDefinition = parentCat.left().value().getLeft().getCategoryDataDefinition(); + SubCategoryDataDefinition subDefinition = subCatData.getSubCategoryDataDefinition(); + GroupingDataDefinition groupingDefinition = groupingData.getGroupingDataDefinition(); + + CategoryDefinition categoryDef = new CategoryDefinition(categoryDefinition); + SubCategoryDefinition subDef = new SubCategoryDefinition(subDefinition); + GroupingDefinition groupingDef = new GroupingDefinition(groupingDefinition); + + if (log.isDebugEnabled()) { + log.debug("Found category {} -> subcategory {} -> grouping {} for product {}", + categoryDefinition.getUniqueId(), subCatData.getUniqueId(), groupingData.getUniqueId(), + product.getUniqueId()); + } + Map> subMap = categoriesDataStructure.get(categoryDef); + if (subMap == null) { + subMap = new HashMap<>(); + categoriesDataStructure.put(categoryDef, subMap); + } + List groupList = subMap.get(subDef); + if (groupList == null) { + groupList = new ArrayList<>(); + subMap.put(subDef, groupList); + } + groupList.add(groupingDef); + } + convertToCategoriesList(product, categoriesDataStructure); + return TitanOperationStatus.OK; + } + + private void convertToCategoriesList(Product product, + Map>> categoriesDataStructure) { + List categoryDataList = product.getCategories(); + if (categoryDataList == null) { + categoryDataList = new ArrayList(); + } + for (Entry>> triple : categoriesDataStructure + .entrySet()) { + CategoryDefinition categoryDefinition = triple.getKey(); + List subList = new ArrayList<>(); + categoryDefinition.setSubcategories(subList); + Map> value = triple.getValue(); + + for (Entry> pair : value.entrySet()) { + SubCategoryDefinition subCategoryDefinition = pair.getKey(); + List list = pair.getValue(); + subList.add(subCategoryDefinition); + subCategoryDefinition.setGroupings(list); + } + categoryDataList.add(categoryDefinition); + } + product.setCategories(categoryDataList); + log.debug("Fetched categories for product {}, categories: {}", product.getUniqueId(), + Arrays.toString(categoryDataList.toArray())); + } + + private ProductMetadataData getProductMetadataDataFromProduct(Product product) { + ProductMetadataData productMetadata = new ProductMetadataData( + (ProductMetadataDataDefinition) product.getComponentMetadataDefinition().getMetadataDataDefinition()); + return productMetadata; + } + + @Override + public boolean isComponentExist(String id) { + return isComponentExist(id, NodeTypeEnum.Product); + } + + // @SuppressWarnings("unchecked") + // @Override + // public Either cloneComponent(T other, + // String version, boolean inTransaction) { + // return (Either) cloneProduct((Product)other, + // version, inTransaction); + // } + + @SuppressWarnings("unchecked") + @Override + public Either cloneComponent(T other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + return (Either) cloneProduct((Product) other, version, targetLifecycle, + inTransaction); + } + + private Either cloneProduct(Product other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + Either result = null; + + try { + String origProductId = other.getUniqueId(); + other.setVersion(version); + other.setUniqueId(null); + + Either counterStatus = getComponentInstanceCoutner(origProductId, + NodeTypeEnum.Product); + if (counterStatus.isRight()) { + StorageOperationStatus status = counterStatus.right().value(); + log.error("failed to get resource instance counter on product {}. status={}", origProductId, + counterStatus); + result = Either.right(status); + return result; + } + + Either createProductMD = createProduct(other, inTransaction); + if (createProductMD.isRight()) { + StorageOperationStatus status = createProductMD.right().value(); + log.debug("Failed to clone product. status= {}", status); + result = Either.right(status); + return result; + } + Product product = createProductMD.left().value(); + + Either, Map>, StorageOperationStatus> cloneInstances = componentInstanceOperation.cloneAllComponentInstancesFromContainerComponent(origProductId, product, + NodeTypeEnum.Product, NodeTypeEnum.Service, targetLifecycle, null); + if (cloneInstances.isRight()) { + result = Either.right(cloneInstances.right().value()); + return result; + } + + Either setResourceInstanceCounter = setComponentInstanceCounter( + product.getUniqueId(), NodeTypeEnum.Product, counterStatus.left().value(), inTransaction); + if (setResourceInstanceCounter.isRight()) { + StorageOperationStatus status = setResourceInstanceCounter.right().value(); + log.error("failed to set resource instance counter on product {}. status={}", product.getUniqueId(), + setResourceInstanceCounter); + result = Either.right(status); + return result; + } + + result = this.getProduct(product.getUniqueId(), inTransaction); + if (result.isRight()) { + log.error("Cannot get full product from the graph. status is {}", result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Product retrieved is {}", json); + } + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private Either getByNamesAndVersion(String nameKey, String nameValue, + String version, Map additionalParams, boolean inTransaction) { + Map props = new HashMap(); + props.put(nameKey, nameValue); + props.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Product.getName()); + if (additionalParams != null && !additionalParams.isEmpty()) { + props.putAll(additionalParams); + } + + Either, TitanOperationStatus> byCriteria = titanGenericDao + .getByCriteria(NodeTypeEnum.Product, props, ProductMetadataData.class); + + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List dataList = byCriteria.left().value(); + if (dataList != null && !dataList.isEmpty()) { + if (dataList.size() > 1) { + log.debug("More that one instance of product for name {} and version {}", nameValue, version); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + ProductMetadataData productData = dataList.get(0); + Either product = getProduct( + productData.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (product.isRight()) { + log.debug("Failed to fetch product, name {} id {}", productData.getMetadataDataDefinition().getName(), + productData.getMetadataDataDefinition().getUniqueId()); + } + return product; + } + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + @Override + public Product getDefaultComponent() { + return new Product(); + } + + @Override + protected StorageOperationStatus updateDerived( + org.openecomp.sdc.be.model.Component component, org.openecomp.sdc.be.model.Component currentComponent, + ComponentMetadataData componentData, Class clazz) { + log.debug("Derived class isn't supported for product"); + return StorageOperationStatus.OK; + } + + @Override + public Either increaseAndGetComponentInstanceCounter(String componentId, + boolean inTransaction) { + return increaseAndGetComponentInstanceCounter(componentId, NodeTypeEnum.Product, inTransaction); + } + + @Override + protected StorageOperationStatus validateCategories(Component currentComponent, Component component, + ComponentMetadataData componentData, NodeTypeEnum type) { + // As agreed with Ella, update categories - delete old and create new + StorageOperationStatus status = StorageOperationStatus.OK; + List newcategories = component.getCategories(); + List currentcategories = currentComponent.getCategories(); + if (newcategories != null) { + if (currentcategories != null && !currentcategories.isEmpty()) { + Either, StorageOperationStatus> findGroupingsForComponent = findGroupingsForComponent( + NodeTypeEnum.ProductGrouping, currentComponent); + if (findGroupingsForComponent.isRight()) { + status = findGroupingsForComponent.right().value(); + } + List groupingDataToDissociate = findGroupingsForComponent.left().value(); + TitanOperationStatus titanStatus = dissociateCategoriesFromProduct((ProductMetadataData) componentData, + groupingDataToDissociate); + if (titanStatus != TitanOperationStatus.OK) { + status = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + } + if (!newcategories.isEmpty()) { + Either, StorageOperationStatus> findGroupingsForComponent = findGroupingsForComponent( + NodeTypeEnum.ProductGrouping, component); + if (findGroupingsForComponent.isRight()) { + status = findGroupingsForComponent.right().value(); + } + List groupingDataToAssociate = findGroupingsForComponent.left().value(); + TitanOperationStatus titanStatus = associateCategoriesToProduct((ProductMetadataData) componentData, + groupingDataToAssociate); + if (titanStatus != TitanOperationStatus.OK) { + status = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + } + } + return status; + } + + @SuppressWarnings("unchecked") + public Either, StorageOperationStatus> getFollowed(String userId, + Set lifecycleStates, Set lastStateStates, boolean inTransaction) { + return (Either, StorageOperationStatus>) (Either) getFollowedComponent( + userId, lifecycleStates, lastStateStates, inTransaction, titanGenericDao, NodeTypeEnum.Product); + } + + @Override + public Either getMetadataComponent(String id, boolean inTransaction) { + return getMetadataComponent(id, NodeTypeEnum.Product, inTransaction); + } + + @Override + Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) { + return convertProductDataToProduct((ProductMetadataData) componentMetadataData); + } + + @Override + public Either validateComponentNameExists(String productName) { + return validateComponentNameUniqueness(productName, titanGenericDao, NodeTypeEnum.Product); + } + + @SuppressWarnings("unchecked") + @Override + public Either markComponentToDelete(Component componentToDelete, + boolean inTransaction) { + // markComponentToDelete is not defined yet for products + return (Either) (Either) deleteProduct( + componentToDelete.getUniqueId(), inTransaction); + } + + @Override + public void rollback() { + titanGenericDao.rollback(); + + } + + @Override + public void commit() { + titanGenericDao.commit(); + } + + @Override + public Either isComponentInUse(String componentId) { + return isComponentInUse(componentId, NodeTypeEnum.Product); + } + + @Override + public Either, StorageOperationStatus> getAllComponentsMarkedForDeletion() { + // markForDeletion for products is not implemented yet + return Either.left(new ArrayList<>()); + } + + public Either getProductByNameAndVersion(String productName, String productVersion, + boolean inTransaction) { + return getByNamesAndVersion(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), + ValidationUtils.normaliseComponentName(productName), productVersion, null, inTransaction); + } + + @SuppressWarnings("unchecked") + @Override + public Either getComponent(String id, + ComponentParametersView componentParametersView, boolean inTransaction) { + return (Either) getProduct(id, false); + } + + public Either updateProduct(Product product, boolean inTransaction, + ComponentParametersView filterResultView) { + return (Either) updateComponentFilterResult(product, inTransaction, + titanGenericDao, product.getClass(), NodeTypeEnum.Service, filterResultView); + } + + @Override + protected Either updateComponentFilterResult(T component, boolean inTransaction, + ComponentParametersView filterResultView) { + return (Either) updateProduct((Product) component, inTransaction, filterResultView); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java new file mode 100644 index 0000000000..7d775b3b3d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java @@ -0,0 +1,2788 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.StringJoiner; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.ObjectCodec; +import org.codehaus.jackson.map.DeserializationContext; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +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.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.IComplexDefaultValue; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.DataTypeData; +import org.openecomp.sdc.be.resources.data.InputValueData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.api.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.reflect.TypeToken; + +import fj.data.Either; + +@Component("property-operation") +public class PropertyOperation extends AbstractOperation implements IPropertyOperation { + + public static void main(String[] args) { + + List buildFunctionPatterns = buildFunctionPatterns(); + + for (Pattern pattern : buildFunctionPatterns) { + + String[] strs = { "str_replace", "{ str_replace:", " {str_replace:", " { str_replace:", "{str_replace:" }; + for (String str : strs) { + Matcher m = pattern.matcher(str); + System.out.println(pattern.pattern() + " " + str + " " + m.find()); + } + } + + } + + public static final String PROPERTY = "property"; + + public PropertyOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(PropertyOperation.class.getName()); + + private static List functionPatterns = null; + + static { + + functionPatterns = buildFunctionPatterns(); + } + + /** + * The value of functions is in a json format. Build pattern for each function name + * + * { str_replace: .... } {str_replace: .... } {str_replace: .... } { str_replace: .... } + * + * @return + */ + private static List buildFunctionPatterns() { + + List functionPatterns = new ArrayList<>(); + + String[] functions = { "get_input", "get_property" }; + + for (String function : functions) { + Pattern pattern = Pattern.compile("^[ ]*\\{[ ]*" + function + ":"); + functionPatterns.add(pattern); + } + + return functionPatterns; + } + + @Override + public Either getPropertyOfResource(String propertyName, String resourceId) { + + String propertyId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName); + + Either getResult = this.titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + if (getResult.isLeft()) { + PropertyData propertyData = getResult.left().value(); + return Either.left(convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId)); + } else { + TitanOperationStatus titanStatus = getResult.right().value(); + log.debug("Node with id {} was not found in the graph. Status: {}", propertyId, titanStatus); + StorageOperationStatus storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + return Either.right(storageOperationStatus); + } + + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.model.operations.api.IPropertyOperation# addPropertyToResource(java.lang.String, org.openecomp.sdc.be.model.PropertyDefinition, org.openecomp.sdc.be.dao.neo4j.datatype.NodeTypeEnum, java.lang.String) + */ + /* + * @Override public Either addPropertyToResource( String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String resourceId) { + * + * StorageOperationStatus isValidProperty = isTypeExistsAndValid(propertyDefinition); if (isValidProperty != StorageOperationStatus.OK) { return Either.right(isValidProperty); } + * + * Either status = addPropertyToGraph(propertyName, propertyDefinition, resourceId); + * + * if (status.isRight()) { titanGenericDao.rollback(); log.error("Failed to add property " + propertyName + " to resource " + resourceId); return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status. right().value())); } else + * { titanGenericDao.commit(); PropertyData propertyData = status.left().value(); + * + * PropertyDefinition propertyDefResult = convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId); log.debug("The returned PropertyDefintion is {}", propertyDefinition); return Either.left(propertyDefResult); } + * + * + * } + */ + private StorageOperationStatus isTypeExistsAndValid(PropertyDefinition propertyDefinition) { + + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyDefinition.getType()); + + if (type == null) { + return StorageOperationStatus.INVALID_TYPE; + } + + String propertyType = propertyDefinition.getType(); + String innerType = null; + String value = propertyDefinition.getDefaultValue(); + + if (propertyType.equals(ToscaPropertyType.LIST) || propertyType.equals(ToscaPropertyType.MAP)) { + SchemaDefinition schema; + if ((schema = propertyDefinition.getSchema()) != null) { + PropertyDataDefinition property; + if ((property = schema.getProperty()) != null) { + innerType = property.getType(); + + } + } + } + + PropertyTypeValidator validator = type.getValidator(); + + if (value == null || (EMPTY_VALUE != null && EMPTY_VALUE.equals(propertyDefinition.getDefaultValue()))) { + return StorageOperationStatus.OK; + } else { + boolean isValid = validator.isValid(value, innerType, null); + if (true == isValid) { + return StorageOperationStatus.OK; + } else { + return StorageOperationStatus.INVALID_VALUE; + } + } + + } + + public PropertyDefinition convertPropertyDataToPropertyDefinition(PropertyData propertyDataResult, String propertyName, String resourceId) { + log.debug("The object returned after create property is {}", propertyDataResult); + + PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition()); + propertyDefResult.setConstraints(convertConstraints(propertyDataResult.getConstraints())); + propertyDefResult.setName(propertyName); + propertyDefResult.setParentUniqueId(resourceId); + + return propertyDefResult; + } + + public static class PropertyConstraintSerialiser implements JsonSerializer { + + @Override + public JsonElement serialize(PropertyConstraint src, Type typeOfSrc, JsonSerializationContext context) { + JsonParser parser = new JsonParser(); + JsonObject result = new JsonObject(); + JsonArray jsonArray = new JsonArray(); + if (src instanceof InRangeConstraint) { + InRangeConstraint rangeConstraint = (InRangeConstraint) src; + jsonArray.add(parser.parse(rangeConstraint.getRangeMinValue())); + jsonArray.add(parser.parse(rangeConstraint.getRangeMaxValue())); + result.add("inRange", jsonArray); + } else if (src instanceof GreaterThanConstraint) { + GreaterThanConstraint greaterThanConstraint = (GreaterThanConstraint) src; + jsonArray.add(parser.parse(greaterThanConstraint.getGreaterThan())); + result.add("greaterThan", jsonArray); + } else if (src instanceof LessOrEqualConstraint) { + LessOrEqualConstraint lessOrEqualConstraint = (LessOrEqualConstraint) src; + jsonArray.add(parser.parse(lessOrEqualConstraint.getLessOrEqual())); + result.add("lessOrEqual", jsonArray); + } else { + log.warn("PropertyConstraint {} is not supported. Ignored.", src.getClass().getName()); + } + + return result; + } + + } + + public static class PropertyConstraintDeserialiser implements JsonDeserializer { + + @Override + public PropertyConstraint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + + PropertyConstraint propertyConstraint = null; + + Set> set = json.getAsJsonObject().entrySet(); + + if (set.size() == 1) { + Entry element = set.iterator().next(); + String key = element.getKey(); + JsonElement value = element.getValue(); + + ConstraintType constraintType = ConstraintType.getByType(key); + if (constraintType == null) { + log.warn("ConstraintType was not found for constraint name:{}", key); + } else { + switch (constraintType) { + case IN_RANGE: + + if (value != null) { + if (value instanceof JsonArray) { + JsonArray rangeArray = (JsonArray) value; + if (rangeArray.size() != 2) { + log.error("The range constraint content is invalid. value = {}", value); + } else { + InRangeConstraint rangeConstraint = new InRangeConstraint(); + String minValue = rangeArray.get(0).getAsString(); + String maxValue = rangeArray.get(1).getAsString(); + rangeConstraint.setRangeMinValue(minValue); + rangeConstraint.setRangeMaxValue(maxValue); + propertyConstraint = rangeConstraint; + } + } + + } else { + log.warn("The value of GreaterThanConstraint is null"); + } + break; + case GREATER_THAN: + if (value != null) { + String asString = value.getAsString(); + log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString); + propertyConstraint = new GreaterThanConstraint(asString); + break; + } else { + log.warn("The value of GreaterThanConstraint is null"); + } + break; + + case LESS_THAN: + if (value != null) { + String asString = value.getAsString(); + log.debug("Before adding value to LessThanConstraint object. value = {}", asString); + propertyConstraint = new LessThanConstraint(asString); + break; + } else { + log.warn("The value of LessThanConstraint is null"); + } + break; + case GREATER_OR_EQUAL: + if (value != null) { + String asString = value.getAsString(); + log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString); + propertyConstraint = new GreaterOrEqualConstraint(asString); + break; + } else { + log.warn("The value of GreaterOrEqualConstraint is null"); + } + break; + case LESS_OR_EQUAL: + + if (value != null) { + String asString = value.getAsString(); + log.debug("Before adding value to LessOrEqualConstraint object. value = {}", asString); + propertyConstraint = new LessOrEqualConstraint(asString); + } else { + log.warn("The value of GreaterThanConstraint is null"); + } + break; + + case VALID_VALUES: + + if (value != null) { + if (value instanceof JsonArray) { + JsonArray rangeArray = (JsonArray) value; + if (rangeArray.size() == 0) { + log.error("The valid values constraint content is invalid. value = {}", value); + } else { + ValidValuesConstraint vvConstraint = new ValidValuesConstraint(); + List validValues = new ArrayList(); + for (JsonElement jsonElement : rangeArray) { + String item = jsonElement.getAsString(); + validValues.add(item); + } + vvConstraint.setValidValues(validValues); + propertyConstraint = vvConstraint; + } + } + + } else { + log.warn("The value of ValidValuesConstraint is null"); + } + break; + + case MIN_LENGTH: + if (value != null) { + int asInt = value.getAsInt(); + log.debug("Before adding value to Min Length object. value = {}", asInt); + propertyConstraint = new MinLengthConstraint(asInt); + break; + } else { + log.warn("The value of MinLengthConstraint is null"); + } + break; + default: + log.warn("Key {} is not supported. Ignored.", key); + } + } + } + + return propertyConstraint; + } + + } + + public TitanOperationStatus addPropertiesToGraph(Map properties, String resourceId, Map dataTypes) { + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + + if (properties != null) { + for (Entry entry : properties.entrySet()) { + + String propertyName = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty); + return TitanOperationStatus.ILLEGAL_ARGUMENT; + } + + Either addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, resourceId); + + if (addPropertyToGraph.isRight()) { + return addPropertyToGraph.right().value(); + } + } + } + + return TitanOperationStatus.OK; + + } + + public TitanOperationStatus addPropertiesToGraph(TitanVertex metadataVertex, Map properties, Map dataTypes, String resourceId) { + + if (properties != null) { + for (Entry entry : properties.entrySet()) { + + String propertyName = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty); + return TitanOperationStatus.ILLEGAL_ARGUMENT; + } + + TitanOperationStatus addPropertyToGraph = addPropertyToGraphByVertex(metadataVertex, propertyName, propertyDefinition, resourceId); + + if (!addPropertyToGraph.equals(TitanOperationStatus.OK)) { + return addPropertyToGraph; + } + } + } + + return TitanOperationStatus.OK; + + } + + public Either addProperty(String propertyName, PropertyDefinition propertyDefinition, String resourceId) { + + Either either = addPropertyToGraph(propertyName, propertyDefinition, resourceId); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + /** + * @param propertyDefinition + * @return + */ + @Override + public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map dataTypes) { + + log.trace("Going to validate property type and value. {}", propertyDefinition); + + String propertyType = propertyDefinition.getType(); + String value = propertyDefinition.getDefaultValue(); + + ToscaPropertyType type = getType(propertyType); + + if (type == null) { + + DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType); + if (dataTypeDefinition == null) { + log.debug("The type {} of property cannot be found.", propertyType); + return StorageOperationStatus.INVALID_TYPE; + } + + StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes); + + return status; + + } + String innerType = null; + + Either checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema()); + if (checkInnerType.isRight()) { + return StorageOperationStatus.INVALID_TYPE; + } + innerType = checkInnerType.left().value(); + + log.trace("After validating property type {}", propertyType); + + boolean isValidProperty = isValidValue(type, value, innerType, dataTypes); + if (false == isValidProperty) { + log.info("The value {} of property from type {} is invalid", value, type); + return StorageOperationStatus.INVALID_VALUE; + } + + PropertyValueConverter converter = type.getConverter(); + + if (isEmptyValue(value)) { + log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE); + propertyDefinition.setDefaultValue(EMPTY_VALUE); + } else if (false == isEmptyValue(value)) { + String convertedValue = converter.convert(value, innerType, dataTypes); + propertyDefinition.setDefaultValue(convertedValue); + } + return StorageOperationStatus.OK; + } + + /* + * public Either validateAndUpdatePropertyValue(String propertyType, String value, String innerType) { + * + * log. trace("Going to validate property value and its type. type = {}, value = {}" ,propertyType, value); + * + * ToscaPropertyType type = getType(propertyType); + * + * if (type == null) { + * + * Either externalDataType = getExternalDataType(propertyType); if (externalDataType.isRight()) { TitanOperationStatus status = externalDataType.right().value(); log.debug("The type " + propertyType + + * " of property cannot be found. Status is " + status); if (status != TitanOperationStatus.NOT_FOUND) { BeEcompErrorManager.getInstance(). logBeInvalidTypeError("validate property type", propertyType, "property"); } return Either.right(false); } + * + * DataTypeDefinition dataTypeDefinition = externalDataType.left().value(); + * + * Either, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value(); return Either.right(false); } + * + * Map allDataTypes = allDataTypesRes.left().value(); + * + * ImmutablePair validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, allDataTypes); + * + * if (validateResult.right.booleanValue() == false) { log.debug("The value {} of property from type {} is invalid", value, propertyType); return Either.right(false); } + * + * JsonElement jsonElement = validateResult.left; + * + * String valueFromJsonElement = getValueFromJsonElement(jsonElement); + * + * return Either.left(valueFromJsonElement); + * + * } + * + * log.trace("After validating property type " + propertyType); + * + * boolean isValidProperty = isValidValue(type, value, innerType); if (false == isValidProperty) { log.debug("The value {} of property from type {} is invalid", value, type); return Either.right(false); } + * + * + * Object convertedValue = value; if (false == isEmptyValue(value)) { PropertyValueConverter converter = type.getConverter(); convertedValue = converter.convert(value, null); } + * + * return Either.left(convertedValue); } + */ + + public Either addPropertyToGraph(String propertyName, PropertyDefinition propertyDefinition, String resourceId) { + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + + List constraints = propertyDefinition.getConstraints(); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName)); + PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints)); + + log.debug("Before adding property to graph {}", propertyData); + Either createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class); + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. Status is {}", propertyName, operationStatus); + return Either.right(operationStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + Either createRelResult = titanGenericDao.createRelation(resourceData, propertyData, GraphEdgeLabels.PROPERTY, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate resource {} to property {} in graph. Status is {}", resourceId, propertyName, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + public TitanOperationStatus addPropertyToGraphByVertex(TitanVertex metadataVertex, String propertyName, PropertyDefinition propertyDefinition, String resourceId) { + + List constraints = propertyDefinition.getConstraints(); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName)); + PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints)); + + log.debug("Before adding property to graph {}", propertyData); + Either createNodeResult = titanGenericDao.createNode(propertyData); + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus); + return operationStatus; + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + TitanVertex propertyVertex = createNodeResult.left().value(); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(metadataVertex, propertyVertex, GraphEdgeLabels.PROPERTY, props); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, createRelResult); + return createRelResult; + } + + return createRelResult; + + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + // public Either + // deletePropertyFromGraphFromBl(String propertyId) { + // + // } + + public Either deleteProperty(String propertyId) { + Either either = deletePropertyFromGraph(propertyId); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + public Either deletePropertyFromGraph(String propertyId) { + log.debug("Before deleting property from graph {}", propertyId); + return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + } + + public Either updateProperty(String propertyId, PropertyDefinition newPropertyDefinition, Map dataTypes) { + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(newPropertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + return Either.right(validateAndUpdateProperty); + } + + Either either = updatePropertyFromGraph(propertyId, newPropertyDefinition); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + public Either updatePropertyFromGraph(String propertyId, PropertyDefinition propertyDefinition) { + if (log.isDebugEnabled()) + log.debug("Before updating property on graph {}", propertyId); + + // get the original property data + Either statusProperty = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + if (statusProperty.isRight()) { + log.debug("Problem while get property with id {}. Reason - {}", propertyId, statusProperty.right().value().name()); + return Either.right(statusProperty.right().value()); + } + PropertyData orgPropertyData = statusProperty.left().value(); + PropertyDataDefinition orgPropertyDataDefinition = orgPropertyData.getPropertyDataDefinition(); + + // create new property data to update + PropertyData newPropertyData = new PropertyData(); + newPropertyData.setPropertyDataDefinition(propertyDefinition); + PropertyDataDefinition newPropertyDataDefinition = newPropertyData.getPropertyDataDefinition(); + + // update the original property data with new values + if (orgPropertyDataDefinition.getDefaultValue() == null) { + orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue()); + } else { + if (!orgPropertyDataDefinition.getDefaultValue().equals(newPropertyDataDefinition.getDefaultValue())) { + orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue()); + } + } + if (orgPropertyDataDefinition.getDescription() == null) { + orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription()); + } else { + if (!orgPropertyDataDefinition.getDescription().equals(newPropertyDataDefinition.getDescription())) { + orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription()); + } + } + if (!orgPropertyDataDefinition.getType().equals(newPropertyDataDefinition.getType())) { + orgPropertyDataDefinition.setType(newPropertyDataDefinition.getType()); + } + if (newPropertyData.getConstraints() != null) { + orgPropertyData.setConstraints(newPropertyData.getConstraints()); + } + orgPropertyDataDefinition.setSchema(newPropertyDataDefinition.getSchema()); + + return titanGenericDao.updateNode(orgPropertyData, PropertyData.class); + } + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + public Either addPropertyToNodeType(String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) { + + List constraints = propertyDefinition.getConstraints(); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName)); + PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints)); + + if (log.isDebugEnabled()) + log.debug("Before adding property to graph {}", propertyData); + Either createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class); + if (log.isDebugEnabled()) + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. Status is {}", propertyName, operationStatus); + return Either.right(operationStatus); + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + + UniqueIdData uniqueIdData = new UniqueIdData(nodeType, uniqueId); + log.debug("Before associating {} to property {}.", uniqueIdData, propertyName); + Either createRelResult = titanGenericDao.createRelation(uniqueIdData, propertyData, GraphEdgeLabels.PROPERTY, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate resource {} to property {} in graph. Status is {}", uniqueId, propertyName, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + public TitanOperationStatus addPropertyToNodeType(TitanVertex elementVertex, String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) { + + List constraints = propertyDefinition.getConstraints(); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName)); + PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints)); + + if (log.isDebugEnabled()) + log.debug("Before adding property to graph {}", propertyData); + Either createNodeResult = titanGenericDao.createNode(propertyData); + if (log.isDebugEnabled()) + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. status is {} ", propertyName, operationStatus); + return operationStatus; + } + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + + TitanOperationStatus createRelResult = titanGenericDao.createEdge(elementVertex, propertyData, GraphEdgeLabels.PROPERTY, props); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to property {} in graph. status is {}", uniqueId, propertyName, createRelResult); + return createRelResult; + } + + return createRelResult; + + } + + public Either, TitanOperationStatus> findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId) { + + Map resourceProps = new HashMap(); + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property, + PropertyData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus operationStatus = childrenNodes.right().value(); + return Either.right(operationStatus); + } + + List> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + log.debug("Property {} is associated to node {}", propertyName, uniqueId); + PropertyData propertyData = immutablePair.getKey(); + PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId); + resourceProps.put(propertyName, propertyDefinition); + } + + } + + log.debug("The properties associated to node {} are {}", uniqueId, resourceProps); + return Either.left(resourceProps); + } + + public Either, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) { + + Either, TitanOperationStatus> propertiesOfNodeRes = findPropertiesOfNode(nodeType, uniqueId); + + if (propertiesOfNodeRes.isRight()) { + TitanOperationStatus status = propertiesOfNodeRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.OK); + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + Map value = propertiesOfNodeRes.left().value(); + for (PropertyDefinition propertyDefinition : value.values()) { + + String propertyUid = propertyDefinition.getUniqueId(); + Either deletePropertyRes = deletePropertyFromGraph(propertyUid); + if (deletePropertyRes.isRight()) { + log.error("Failed to delete property with id " + propertyUid); + TitanOperationStatus status = deletePropertyRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } + + log.debug("The properties deleted from node {} are {}", uniqueId, value); + return Either.left(value); + } + + /** + * fetch all properties under a given resource(includes its parents' resources) + * + * @param resourceId + * @param properties + * @return + */ + public TitanOperationStatus findAllResourcePropertiesRecursively(String resourceId, List properties) { + final NodeElementFetcher singleNodeFetcher = (resourceIdParam, attributesParam) -> findPropertiesOfNode(NodeTypeEnum.Resource, resourceIdParam, attributesParam); + return findAllResourceElementsDefinitionRecursively(resourceId, properties, singleNodeFetcher); + } + + /** + * + * + * @param nodeType + * @param uniqueId + * @param properties + * @return + */ + protected TitanOperationStatus findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId, List properties) { + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property, + PropertyData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return status; + } + + List> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + if (log.isDebugEnabled()) + log.debug("Property {} is associated to node {}", propertyName, uniqueId); + PropertyData propertyData = immutablePair.getKey(); + PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId); + + properties.add(propertyDefinition); + + if (log.isTraceEnabled()) + log.trace("findPropertiesOfNode - property {} associated to node {}", propertyDefinition, uniqueId); + } + + } + + return TitanOperationStatus.OK; + } + + public boolean isPropertyExist(List properties, String resourceUid, String propertyName) { + + if (properties == null) { + return false; + } + + for (PropertyDefinition propertyDefinition : properties) { + String parentUniqueId = propertyDefinition.getParentUniqueId(); + String name = propertyDefinition.getName(); + + if (parentUniqueId.equals(resourceUid) && name.equals(propertyName)) { + return true; + } + } + + return false; + + } + + /** + * add property to resource instance + * + * @param innerType + * TODO // * @param resourceInstanceProperty // * @param resourceInstanceId // * @param index + * + * @return + */ + /* + * public Either addPropertyToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index) { + * + * Either findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + * + * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * String propertyId = resourceInstanceProperty.getUniqueId(); Either findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + * + * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { + * + * PropertyData propertyData = findPropertyDefRes.left().value(); ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value(); + * + * ImmutablePair isPropertyValueExists = findPropertyValue(resourceInstanceId, propertyId); if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { log.debug("The property " + propertyId + + * " already added to the resource instance " + resourceInstanceId); resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight ()); Either updatePropertyOfResourceInstance = + * updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) { BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance", + * "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); return Either.right(updatePropertyOfResourceInstance.right().value()); } return + * Either.left(updatePropertyOfResourceInstance.left().value()); } + * + * if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { log.debug("After finding property value of {} on component instance {}", propertyId, resourceInstanceId); return Either.right(isPropertyValueExists.getLeft()); } + * + * String propertyType = propertyData.getPropertyDataDefinition().getType(); String value = resourceInstanceProperty.getValue(); Either isValid = validateAndUpdatePropertyValue(propertyType, value); + * + * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != null) { + * newValue = object.toString(); } } + * + * String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid( resourceInstanceData.getUniqueId(), index); PropertyValueData propertyValueData = new PropertyValueData(); propertyValueData.setUniqueId(uniqueId); + * propertyValueData.setValue(newValue); + * + * ImmutablePair pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance(). + * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } addRulesToNewPropertyValue(propertyValueData, + * resourceInstanceProperty, resourceInstanceId); + * + * log.debug("Before adding property value to graph {}", propertyValueData); Either createNodeResult = titanGenericDao .createNode(propertyValueData, PropertyValueData.class); + * log.debug("After adding property value to graph {}", propertyValueData); + * + * Either createRelResult = titanGenericDao .createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null); + * + * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate property value " + uniqueId + " to property " + propertyId + + * " in graph. status is " + operationStatus); return Either.right(operationStatus); } + * + * createRelResult = titanGenericDao .createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null); + * + * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId + + * " in graph. status is " + operationStatus); return Either.right(operationStatus); } + * + * return Either.left(createNodeResult.left().value()); } else { log.error("property value already exists."); return Either.right(TitanOperationStatus.ALREADY_EXIST); } + * + * } + */ + public ImmutablePair validateAndUpdateRules(String propertyType, List rules, String innerType, Map dataTypes, boolean isValidate) { + + if (rules == null || rules.isEmpty() == true) { + return new ImmutablePair(null, true); + } + + for (PropertyRule rule : rules) { + String value = rule.getValue(); + Either updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes); + if (updateResult.isRight()) { + Boolean status = updateResult.right().value(); + if (status == false) { + return new ImmutablePair(value, status); + } + } else { + String newValue = null; + Object object = updateResult.left().value(); + if (object != null) { + newValue = object.toString(); + } + rule.setValue(newValue); + } + } + + return new ImmutablePair(null, true); + } + + public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) { + + List rules = resourceInstanceProperty.getRules(); + if (rules == null) { + PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId); + rules = new ArrayList<>(); + rules.add(propertyRule); + } else { + rules = sortRules(rules); + } + + propertyValueData.setRules(rules); + } + + private PropertyRule buildRuleFromPath(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) { + List path = resourceInstanceProperty.getPath(); + // FOR BC. Since old Property values on VFC/VF does not have rules on + // graph. + // Update could be done on one level only, thus we can use this + // operation to avoid migration. + if (path == null || path.isEmpty() == true) { + path = new ArrayList<>(); + path.add(resourceInstanceId); + } + PropertyRule propertyRule = new PropertyRule(); + propertyRule.setRule(path); + propertyRule.setValue(propertyValueData.getValue()); + return propertyRule; + } + + private List sortRules(List rules) { + + // TODO: sort the rules by size and binary representation. + // (x, y, .+) --> 110 6 priority 1 + // (x, .+, z) --> 101 5 priority 2 + + return rules; + } + + public ImmutablePair findPropertyValue(String resourceInstanceId, String propertyId) { + + log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId); + + Either, TitanOperationStatus> getAllRes = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceId); + if (getAllRes.isRight()) { + TitanOperationStatus status = getAllRes.right().value(); + log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status); + return new ImmutablePair(status, null); + } + + List list = getAllRes.left().value(); + if (list != null) { + for (ComponentInstanceProperty instanceProperty : list) { + String propertyUniqueId = instanceProperty.getUniqueId(); + String valueUniqueUid = instanceProperty.getValueUniqueUid(); + log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid); + if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) { + log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId); + return new ImmutablePair(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid); + } + } + } + + return new ImmutablePair(TitanOperationStatus.NOT_FOUND, null); + } + + /** + * update value of property on resource instance + * + * @param resourceInstanceProperty + * @param resourceInstanceId + * @return + */ + /* + * public Either updatePropertyOfResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) { + * + * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// /// Either findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder + * .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + * + * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * String propertyId = resourceInstanceProperty.getUniqueId(); Either findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + * + * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); return Either.right(status); } + * + * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { return Either.right(TitanOperationStatus.INVALID_ID); } else { Either findPropertyValueRes = + * titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, PropertyValueData.class); if (findPropertyValueRes.isRight()) { TitanOperationStatus status = findPropertyValueRes.right().value(); if + * (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * String value = resourceInstanceProperty.getValue(); + * + * Either, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, + * PropertyData.class); + * + * if (child.isRight()) { TitanOperationStatus status = child.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * PropertyData propertyData = child.left().value().left; String propertyType = propertyData.getPropertyDataDefinition().getType(); + * + * log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType); + * + * Either isValid = validateAndUpdatePropertyValue(propertyType, value); + * + * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != null) { + * newValue = object.toString(); } } PropertyValueData propertyValueData = findPropertyValueRes.left().value(); log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue); + * propertyValueData.setValue(newValue); + * + * ImmutablePair pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance(). + * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } updateRulesInPropertyValue(propertyValueData, + * resourceInstanceProperty, resourceInstanceId); + * + * Either updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); if (updateRes.isRight()) { TitanOperationStatus status = updateRes.right().value(); return + * Either.right(status); } else { return Either.left(updateRes.left().value()); } } + * + * } + */ + + public void updateRulesInPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) { + + List currentRules = propertyValueData.getRules(); + + List rules = resourceInstanceProperty.getRules(); + // if rules are not supported. + if (rules == null) { + + PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId); + rules = new ArrayList<>(); + rules.add(propertyRule); + + if (currentRules != null) { + rules = mergeRules(currentRules, rules); + } + + } else { + // Full mode. all rules are sent in update operation. + rules = sortRules(rules); + } + + propertyValueData.setRules(rules); + + } + + private List mergeRules(List currentRules, List newRules) { + + List mergedRules = new ArrayList<>(); + + if (newRules == null || newRules.isEmpty() == true) { + return currentRules; + } + + for (PropertyRule rule : currentRules) { + PropertyRule propertyRule = new PropertyRule(rule.getRule(), rule.getValue()); + mergedRules.add(propertyRule); + } + + for (PropertyRule rule : newRules) { + PropertyRule foundRule = findRuleInList(rule, mergedRules); + if (foundRule != null) { + foundRule.setValue(rule.getValue()); + } else { + mergedRules.add(rule); + } + } + + return mergedRules; + } + + private PropertyRule findRuleInList(PropertyRule rule, List rules) { + + if (rules == null || rules.isEmpty() == true || rule.getRule() == null || rule.getRule().isEmpty() == true) { + return null; + } + + PropertyRule foundRule = null; + for (PropertyRule propertyRule : rules) { + if (rule.getRuleSize() != propertyRule.getRuleSize()) { + continue; + } + boolean equals = propertyRule.compareRule(rule); + if (equals == true) { + foundRule = propertyRule; + break; + } + } + + return foundRule; + } + + /** + * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value... + * + * @param resourceInstanceUid + * @return + */ + public Either, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid) { + + return getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance); + + } + + /* + * public Either addPropertyValueToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction) { + * + * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// /// + * + * Either result = null; + * + * try { + * + * Either eitherStatus = this .addPropertyToResourceInstance(resourceInstanceProperty, resourceInstanceId, index); + * + * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result = + * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value(); + * + * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty); + * + * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } } + * + * finally { if (false == inTransaction) { if (result == null || result.isRight()) { log.error("Going to execute rollback on graph."); titanGenericDao.rollback(); } else { log.debug("Going to execute commit on graph."); titanGenericDao.commit(); + * } } } + * + * } + * + * public Either updatePropertyValueInResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction) { + * + * Either result = null; + * + * try { //TODO: verify validUniqueId exists Either eitherStatus = this .updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId); + * + * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result = + * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value(); + * + * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty); + * + * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } } + * + * finally { if (false == inTransaction) { if (result == null || result.isRight()) { log.error("Going to execute rollback on graph."); titanGenericDao.rollback(); } else { log.debug("Going to execute commit on graph."); titanGenericDao.commit(); + * } } } + * + * } + */ + + public Either removePropertyOfResourceInstance(String propertyValueUid, String resourceInstanceId) { + + Either findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + Either findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, PropertyValueData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + Either relation = titanGenericDao.getRelation(findResInstanceRes.left().value(), findPropertyDefRes.left().value(), GraphEdgeLabels.PROPERTY_VALUE); + if (relation.isRight()) { + // TODO: add error in case of error + TitanOperationStatus status = relation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + Either deleteNode = titanGenericDao.deleteNode(findPropertyDefRes.left().value(), PropertyValueData.class); + if (deleteNode.isRight()) { + return Either.right(deleteNode.right().value()); + } + PropertyValueData value = deleteNode.left().value(); + return Either.left(value); + + } + + public Either removePropertyValueFromResourceInstance(String propertyValueUid, String resourceInstanceId, boolean inTransaction) { + + Either result = null; + + try { + + Either eitherStatus = this.removePropertyOfResourceInstance(propertyValueUid, resourceInstanceId); + + if (eitherStatus.isRight()) { + log.error("Failed to remove property value {} from resource instance {} in Graph. status is {}", propertyValueUid, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + PropertyValueData propertyValueData = eitherStatus.left().value(); + + ComponentInstanceProperty propertyValueResult = new ComponentInstanceProperty(); + propertyValueResult.setUniqueId(resourceInstanceId); + propertyValueResult.setValue(propertyValueData.getValue()); + + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + result = Either.left(propertyValueResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public ComponentInstanceProperty buildResourceInstanceProperty(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty) { + + String value = propertyValueData.getValue(); + String uid = propertyValueData.getUniqueId(); + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(resourceInstanceProperty, value, uid); + instanceProperty.setPath(resourceInstanceProperty.getPath()); + + return instanceProperty; + } + + public static class PropertyConstraintJacksonDeserialiser extends org.codehaus.jackson.map.JsonDeserializer { + + @Override + public PropertyConstraint deserialize(org.codehaus.jackson.JsonParser json, DeserializationContext context) throws IOException, JsonProcessingException { + + ObjectCodec oc = json.getCodec(); + JsonNode node = oc.readTree(json); + return null; + } + } + + @Override + public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, Map dataTypes) { + if (propertyDefinition == null) { + return false; + } + boolean isValid = false; + String innerType = null; + String propertyType = propertyDefinition.getType(); + ToscaPropertyType type = getType(propertyType); + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propertyDefinition.getSchema(); + if (def == null) { + return false; + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + return false; + } + innerType = propDef.getType(); + } + String value = propertyDefinition.getDefaultValue(); + if (type != null) { + isValid = isValidValue(type, value, innerType, dataTypes); + } else { + log.trace("The given type {} is not a pre defined one.", propertyType); + + DataTypeDefinition foundDt = dataTypes.get(propertyType); + if (foundDt != null) { + isValid = isValidComplexValue(foundDt, value, dataTypes); + } else { + isValid = false; + } + } + return isValid; + } + + public boolean isPropertyTypeValid(IComplexDefaultValue property) { + + if (property == null) { + return false; + } + + if (ToscaPropertyType.isValidType(property.getType()) == null) { + + Either definedInDataTypes = isDefinedInDataTypes(property.getType()); + + if (definedInDataTypes.isRight()) { + return false; + } else { + Boolean isExist = definedInDataTypes.left().value(); + return isExist.booleanValue(); + } + + } + return true; + } + + @Override + public ImmutablePair isPropertyInnerTypeValid(IComplexDefaultValue property, Map dataTypes) { + + if (property == null) { + return new ImmutablePair(null, false); + } + + SchemaDefinition schema; + PropertyDataDefinition innerProp; + String innerType = null; + if ((schema = property.getSchema()) != null) { + if ((innerProp = schema.getProperty()) != null) { + innerType = innerProp.getType(); + } + } + + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType == null) { + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + if (dataTypeDefinition == null) { + log.debug("The inner type {} is not a data type", innerType); + return new ImmutablePair(innerType, false); + } else { + log.debug("The inner type {} is a data type. Data type definition is {}", innerType, dataTypeDefinition); + } + } + + return new ImmutablePair(innerType, true); + } + + private boolean isValidComplexValue(DataTypeDefinition foundDt, String value, Map dataTypes) { + /* + * Either, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value(); + * log.debug("Failed to fetch data types from graph. Status is {}", status); return false; } + * + * Map allDataTypes = allDataTypesRes.left().value(); + */ + ImmutablePair validateAndUpdate = dataTypeValidatorConverter.validateAndUpdate(value, foundDt, dataTypes); + + log.trace("The result after validating complex value of type {} is {}", foundDt.getName(), validateAndUpdate); + + return validateAndUpdate.right.booleanValue(); + + } + + private Either, TitanOperationStatus> findAllDataTypeDefinition(DataTypeDefinition dataTypeDefinition) { + + Map nameToDataTypeDef = new HashMap<>(); + + DataTypeDefinition typeDefinition = dataTypeDefinition; + + while (typeDefinition != null) { + + List properties = typeDefinition.getProperties(); + if (properties != null) { + for (PropertyDefinition propertyDefinition : properties) { + String type = propertyDefinition.getType(); + Either dataTypeByName = this.getDataTypeUsingName(type); + if (dataTypeByName.isRight()) { + return Either.right(dataTypeByName.right().value()); + } else { + DataTypeDefinition value = dataTypeByName.left().value(); + if (false == nameToDataTypeDef.containsKey(type)) { + nameToDataTypeDef.put(type, value); + } + } + + } + } + + typeDefinition = typeDefinition.getDerivedFrom(); + } + + return Either.left(nameToDataTypeDef); + } + + public Either, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) { + + // Either + // findResInstanceRes = + // titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), + // resourceInstanceUid, ComponentInstanceData.class); + Either findResInstanceRes = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + // Either>, + // TitanOperationStatus> propertyImplNodes = + // titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), + // resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE, + // NodeTypeEnum.PropertyValue, PropertyValueData.class); + Either>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List> list = propertyImplNodes.left().value(); + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List result = new ArrayList<>(); + for (ImmutablePair propertyValue : list) { + TitanVertex propertyValueDataVertex = propertyValue.getLeft(); + String propertyValueUid = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String value = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.VALUE.getProperty()); + + ImmutablePair propertyDefPair = titanGenericDao.getChildVertex(propertyValueDataVertex, GraphEdgeLabels.PROPERTY_IMPL); + if (propertyDefPair == null) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + Map properties = titanGenericDao.getProperties(propertyValueDataVertex); + PropertyValueData propertyValueData = GraphElementFactory.createElement(NodeTypeEnum.PropertyValue.getName(), GraphElementTypeEnum.Node, properties, PropertyValueData.class); + String propertyUniqueId = (String) titanGenericDao.getProperty(propertyDefPair.left, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueUid); + // set rules + resourceInstanceProperty.setRules(propertyValueData.getRules()); + + result.add(resourceInstanceProperty); + } + + return Either.left(result); + } + + /** + * Find the default value from the list of component instances. Start the search from the second component instance + * + * @param pathOfComponentInstances + * @param propertyUniqueId + * @param defaultValue + * @return + */ + public Either findDefaultValueFromSecondPosition(List pathOfComponentInstances, String propertyUniqueId, String defaultValue) { + + log.trace("In find default value: path=" + pathOfComponentInstances + "propertyUniqId=" + propertyUniqueId + "defaultValue=" + defaultValue); + + if (pathOfComponentInstances == null || pathOfComponentInstances.size() < 2) { + return Either.left(defaultValue); + } + + String result = defaultValue; + + for (int i = 1; i < pathOfComponentInstances.size(); i++) { + String compInstanceId = pathOfComponentInstances.get(i); + + Either, TitanOperationStatus> propertyValuesResult = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(compInstanceId, NodeTypeEnum.ResourceInstance); + + log.trace("After fetching properties values of component instance {}. {}", compInstanceId, propertyValuesResult); + + if (propertyValuesResult.isRight()) { + TitanOperationStatus status = propertyValuesResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } else { + continue; + } + } + + ComponentInstanceProperty foundCompInstanceProperty = fetchByPropertyUid(propertyValuesResult.left().value(), propertyUniqueId); + log.trace("After finding the component instance property on {}. {}", compInstanceId, foundCompInstanceProperty); + + if (foundCompInstanceProperty == null) { + continue; + } + + List rules = getOrBuildRulesIfNotExists(pathOfComponentInstances.size() - i, pathOfComponentInstances.get(i), foundCompInstanceProperty.getRules(), foundCompInstanceProperty.getValue()); + + log.trace("Rules of property {} on component instance {} are {}", propertyUniqueId, compInstanceId, rules); + PropertyRule matchedRule = findMatchRule(pathOfComponentInstances, i, rules); + log.trace("Match rule is {}", matchedRule); + + if (matchedRule != null) { + result = matchedRule.getValue(); + break; + } + + } + + return Either.left(result); + + } + + private ComponentInstanceProperty fetchByPropertyUid(List list, String propertyUniqueId) { + + ComponentInstanceProperty result = null; + + if (list == null) { + return null; + } + + for (ComponentInstanceProperty instProperty : list) { + if (instProperty.getUniqueId().equals(propertyUniqueId)) { + result = instProperty; + break; + } + } + + return result; + } + + private List getOrBuildRulesIfNotExists(int ruleSize, String compInstanceId, List rules, String value) { + + if (rules != null) { + return rules; + } + + rules = buildDefaultRule(compInstanceId, ruleSize, value); + + return rules; + + } + + private List getRulesOfPropertyValue(int size, String instanceId, ComponentInstanceProperty componentInstanceProperty) { + List rules = componentInstanceProperty.getRules(); + if (rules == null) { + rules = buildDefaultRule(instanceId, size, componentInstanceProperty.getValue()); + } + return rules; + } + + private List buildDefaultRule(String componentInstanceId, int size, String value) { + + List rules = new ArrayList<>(); + List rule = new ArrayList<>(); + rule.add(componentInstanceId); + for (int i = 0; i < size - 1; i++) { + rule.add(PropertyRule.RULE_ANY_MATCH); + } + PropertyRule propertyRule = new PropertyRule(rule, value); + rules.add(propertyRule); + + return rules; + + } + + private PropertyRule findMatchRule(List pathOfInstances, int level, List rules) { + + PropertyRule propertyRule = null; + + String stringForMatch = buildStringForMatch(pathOfInstances, level); + + String firstCompInstance = pathOfInstances.get(level); + + if (rules != null) { + + for (PropertyRule rule : rules) { + + int ruleSize = rule.getRule().size(); + // check the length of the rule equals to the length of the + // instances path. + if (ruleSize != pathOfInstances.size() - level) { + continue; + } + // check that the rule starts with correct component instance id + if (false == checkFirstItem(firstCompInstance, rule.getFirstToken())) { + continue; + } + + String secondToken = rule.getToken(2); + if (secondToken != null && (secondToken.equals(PropertyRule.FORCE_ALL) || secondToken.equals(PropertyRule.ALL))) { + propertyRule = rule; + break; + } + + String patternStr = buildStringForMatch(rule.getRule(), 0); + + Pattern pattern = Pattern.compile(patternStr); + + Matcher matcher = pattern.matcher(stringForMatch); + + if (matcher.matches()) { + log.trace("{} matches the rule {}", stringForMatch, patternStr); + propertyRule = rule; + break; + } + } + + } + + return propertyRule; + } + + private boolean checkFirstItem(String left, String right) { + if (left != null && left.equals(right)) { + return true; + } + return false; + } + + private String buildStringForMatch(List pathOfInstances, int level) { + StringBuilder builder = new StringBuilder(); + + for (int i = level; i < pathOfInstances.size(); i++) { + builder.append(pathOfInstances.get(i)); + if (i < pathOfInstances.size() - 1) { + builder.append("#"); + } + } + return builder.toString(); + } + + public void updatePropertyByBestMatch(String propertyUniqueId, ComponentInstanceProperty instanceProperty, Map instanceIdToValue) { + + List pathOfInstances = instanceProperty.getPath(); + int level = 0; + int size = pathOfInstances.size(); + int numberOfMatches = 0; + for (String instanceId : pathOfInstances) { + ComponentInstanceProperty componentInstanceProperty = instanceIdToValue.get(instanceId); + + if (componentInstanceProperty != null) { + + List rules = getRulesOfPropertyValue(size - level, instanceId, componentInstanceProperty); + // If it is the first level instance, then update valueUniuqeId + // parameter in order to know on update that + // we should update and not create new node on graph. + if (level == 0) { + instanceProperty.setValueUniqueUid(componentInstanceProperty.getValueUniqueUid()); + instanceProperty.setRules(rules); + } + + PropertyRule rule = findMatchRule(pathOfInstances, level, rules); + if (rule != null) { + numberOfMatches++; + String value = rule.getValue(); + if (numberOfMatches == 1) { + instanceProperty.setValue(value); + if (log.isDebugEnabled()) { + log.debug("Set the value of property " + propertyUniqueId + " " + instanceProperty.getName() + " on path " + pathOfInstances + " to be " + value); + } + } else if (numberOfMatches == 2) { + // In case of another property value match, then use the + // value to be the default value of the property. + instanceProperty.setDefaultValue(value); + if (log.isDebugEnabled()) { + log.debug("Set the default value of property " + propertyUniqueId + " " + instanceProperty.getName() + " on path " + pathOfInstances + " to be " + value); + } + break; + } + } + } + level++; + } + + } + + public void updatePropertiesByPropertyValues(Map> resourceInstancesProperties, Map> values) { + + if (resourceInstancesProperties == null) { + return; + } + + List allProperties = new ArrayList<>(); + Collection> properties = resourceInstancesProperties.values(); + if (properties != null) { + Iterator> iterator = properties.iterator(); + while (iterator.hasNext()) { + List compInstancePropertyList = iterator.next(); + allProperties.addAll(compInstancePropertyList); + } + } + + // Go over each property and check whether there is a rule which updates + // it + for (ComponentInstanceProperty instanceProperty : allProperties) { + + String propertyUniqueId = instanceProperty.getUniqueId(); + + // get the changes per componentInstanceId. + Map instanceIdToValue = values.get(propertyUniqueId); + + if (instanceIdToValue == null) { + continue; + } + + this.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + } + + } + + /** + * + * Add data type to graph. + * + * 1. Add data type node + * + * 2. Add edge between the former node to its parent(if exists) + * + * 3. Add property node and associate it to the node created at #1. (per property & if exists) + * + * @param dataTypeDefinition + * @return + */ + private Either addDataTypeToGraph(DataTypeDefinition dataTypeDefinition) { + + log.debug("Got data type " + dataTypeDefinition); + + String dtUniqueId = UniqueIdBuilder.buildDataTypeUid(dataTypeDefinition.getName()); + + DataTypeData dataTypeData = buildDataTypeData(dataTypeDefinition, dtUniqueId); + + log.debug("Before adding data type to graph. dataTypeData = " + dataTypeData); + Either createDataTypeResult = titanGenericDao.createNode(dataTypeData, DataTypeData.class); + log.debug("After adding data type to graph. status is = {}", createDataTypeResult); + + if (createDataTypeResult.isRight()) { + TitanOperationStatus operationStatus = createDataTypeResult.right().value(); + log.debug("Failed to data type " + dataTypeDefinition.getName() + " to graph. status is " + operationStatus); + BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", NodeTypeEnum.DataType.getName()); + return Either.right(operationStatus); + } + + DataTypeData resultCTD = createDataTypeResult.left().value(); + List properties = dataTypeDefinition.getProperties(); + Either, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(resultCTD.getUniqueId(), properties); + if (addPropertiesToDataType.isRight()) { + log.debug("Failed add properties " + properties + " to data type " + dataTypeDefinition.getName()); + return Either.right(addPropertiesToDataType.right().value()); + } + + String derivedFrom = dataTypeDefinition.getDerivedFromName(); + if (derivedFrom != null) { + log.debug("Before creating relation between data type " + dtUniqueId + " to its parent " + derivedFrom); + UniqueIdData from = new UniqueIdData(NodeTypeEnum.DataType, dtUniqueId); + + String deriveFromUid = UniqueIdBuilder.buildDataTypeUid(derivedFrom); + UniqueIdData to = new UniqueIdData(NodeTypeEnum.DataType, deriveFromUid); + Either createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null); + log.debug("After create relation between capability type " + dtUniqueId + " to its parent " + derivedFrom + ". status is " + createRelation); + if (createRelation.isRight()) { + return Either.right(createRelation.right().value()); + } + } + + return Either.left(createDataTypeResult.left().value()); + + } + + private DataTypeData buildDataTypeData(DataTypeDefinition dataTypeDefinition, String ctUniqueId) { + + DataTypeData dataTypeData = new DataTypeData(dataTypeDefinition); + + dataTypeData.getDataTypeDataDefinition().setUniqueId(ctUniqueId); + Long creationDate = dataTypeData.getDataTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + dataTypeData.getDataTypeDataDefinition().setCreationTime(creationDate); + dataTypeData.getDataTypeDataDefinition().setModificationTime(creationDate); + + return dataTypeData; + } + + /** + * add properties to capability type. + * + * Per property, add a property node and associate it to the capability type + * + * @param uniqueId + * @param properties + * @return + */ + private Either, TitanOperationStatus> addPropertiesToDataType(String uniqueId, List properties) { + + Map propertiesData = new HashMap(); + + if (properties != null && false == properties.isEmpty()) { + for (PropertyDefinition propertyDefinition : properties) { + String propertyName = propertyDefinition.getName(); + + String propertyType = propertyDefinition.getType(); + Either validPropertyType = isValidPropertyType(propertyType); + if (validPropertyType.isRight()) { + log.debug("Data type " + uniqueId + " contains invalid property type " + propertyType); + return Either.right(validPropertyType.right().value()); + } + Boolean isValid = validPropertyType.left().value(); + if (isValid == null || isValid.booleanValue() == false) { + log.debug("Data type " + uniqueId + " contains invalid property type " + propertyType); + return Either.right(TitanOperationStatus.INVALID_TYPE); + } + + Either addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinition, NodeTypeEnum.DataType, uniqueId); + if (addPropertyToNodeType.isRight()) { + TitanOperationStatus operationStatus = addPropertyToNodeType.right().value(); + log.debug("Failed to associate data type " + uniqueId + " to property " + propertyName + " in graph. status is " + operationStatus); + BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to associate property to data type. Status is " + operationStatus, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } + propertiesData.put(propertyName, addPropertyToNodeType.left().value()); + } + + DataTypeData dataTypeData = new DataTypeData(); + dataTypeData.getDataTypeDataDefinition().setUniqueId(uniqueId); + long modificationTime = System.currentTimeMillis(); + dataTypeData.getDataTypeDataDefinition().setModificationTime(modificationTime); + + Either updateNode = titanGenericDao.updateNode(dataTypeData, DataTypeData.class); + if (updateNode.isRight()) { + TitanOperationStatus operationStatus = updateNode.right().value(); + log.debug("Failed to update modification time data type " + uniqueId + " from graph. status is " + operationStatus); + BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to fetch data type. Status is " + operationStatus, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } else { + log.debug("Update data type uid {}. Set modification time to {}", uniqueId, modificationTime); + } + + } + + return Either.left(propertiesData); + + } + + /** + * Build Data type object from graph by unique id + * + * @param uniqueId + * @return + */ + public Either getDataTypeByUid(String uniqueId) { + + Either result = null; + + Either dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class); + + if (dataTypesRes.isRight()) { + TitanOperationStatus status = dataTypesRes.right().value(); + log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status); + return Either.right(status); + } + + DataTypeData ctData = dataTypesRes.left().value(); + DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of data type " + uniqueId); + return Either.right(propertiesStatus); + } + + Either, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType, + DataTypeData.class); + log.debug("After retrieving DERIVED_FROM node of " + uniqueId + ". status is " + parentNode); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the parent data type of data type " + uniqueId + ". status is " + titanOperationStatus); + result = Either.right(titanOperationStatus); + return result; + } + } else { + // derived from node was found + ImmutablePair immutablePair = parentNode.left().value(); + DataTypeData parentCT = immutablePair.getKey(); + + String parentUniqueId = parentCT.getUniqueId(); + Either dataTypeByUid = getDataTypeByUid(parentUniqueId); + + if (dataTypeByUid.isRight()) { + return Either.right(dataTypeByUid.right().value()); + } + + DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value(); + + dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition); + + } + result = Either.left(dataTypeDefinition); + + return result; + } + + private TitanOperationStatus fillProperties(String uniqueId, DataTypeDefinition dataTypeDefinition) { + + Either, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.DataType, uniqueId); + if (findPropertiesOfNode.isRight()) { + TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value(); + log.debug("After looking for properties of vertex " + uniqueId + ". status is " + titanOperationStatus); + if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) { + return TitanOperationStatus.OK; + } else { + return titanOperationStatus; + } + } else { + Map properties = findPropertiesOfNode.left().value(); + if (properties != null && properties.isEmpty() == false) { + List listOfProps = new ArrayList<>(); + + for (Entry entry : properties.entrySet()) { + String propName = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition); + newPropertyDefinition.setName(propName); + listOfProps.add(newPropertyDefinition); + } + dataTypeDefinition.setProperties(listOfProps); + } + return TitanOperationStatus.OK; + } + } + + @Override + public Either addDataType(DataTypeDefinition dataTypeDefinition, boolean inTransaction) { + + Either result = null; + + try { + + Either eitherStatus = addDataTypeToGraph(dataTypeDefinition); + + if (eitherStatus.isRight()) { + log.debug("Failed to add data type {} to Graph. status is {}", dataTypeDefinition, eitherStatus.right().value().name()); + BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", "DataType"); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + DataTypeData capabilityTypeData = eitherStatus.left().value(); + + DataTypeDefinition dataTypeDefResult = convertDTDataToDTDefinition(capabilityTypeData); + log.debug("The returned CapabilityTypeDefinition is " + dataTypeDefResult); + result = Either.left(dataTypeDefResult); + return result; + } + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either addDataType(DataTypeDefinition dataTypeDefinition) { + return addDataType(dataTypeDefinition, true); + } + + @Override + public Either getDataTypeByName(String name, boolean inTransaction) { + + Either result = null; + try { + + String dtUid = UniqueIdBuilder.buildDataTypeUid(name); + Either ctResult = this.getDataTypeByUid(dtUid); + + if (ctResult.isRight()) { + TitanOperationStatus status = ctResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to retrieve information on capability type " + name + "status is " + status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value())); + return result; + } + + result = Either.left(ctResult.left().value()); + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either getDataTypeByName(String name) { + return getDataTypeByName(name, true); + } + + @Override + public Either getDataTypeByNameWithoutDerived(String name) { + return getDataTypeByNameWithoutDerived(name, true); + } + + @Override + public Either getDataTypeByNameWithoutDerived(String name, boolean inTransaction) { + + Either result = null; + try { + + String uid = UniqueIdBuilder.buildDataTypeUid(name); + Either ctResult = this.getDataTypeByUidWithoutDerivedDataTypes(uid); + + if (ctResult.isRight()) { + TitanOperationStatus status = ctResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to retrieve information on capability type " + name + "status is " + status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value())); + return result; + } + + result = Either.left(ctResult.left().value()); + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either getDataTypeByUidWithoutDerivedDataTypes(String uniqueId) { + + Either dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class); + + if (dataTypesRes.isRight()) { + TitanOperationStatus status = dataTypesRes.right().value(); + log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status); + return Either.right(status); + } + + DataTypeData ctData = dataTypesRes.left().value(); + DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of data type " + uniqueId); + return Either.right(propertiesStatus); + } + + return Either.left(dataTypeDefinition); + } + + public Either getDataTypeByNameWithoutDerivedDataTypes(String name) { + + String uid = UniqueIdBuilder.buildDataTypeUid(name); + return getDataTypeByUidWithoutDerivedDataTypes(uid); + + } + + /** + * + * convert between graph Node object to Java object + * + * @param dataTypeData + * @return + */ + protected DataTypeDefinition convertDTDataToDTDefinition(DataTypeData dataTypeData) { + log.debug("The object returned after create data type is " + dataTypeData); + + DataTypeDefinition dataTypeDefResult = new DataTypeDefinition(dataTypeData.getDataTypeDataDefinition()); + + return dataTypeDefResult; + } + + private Either isValidPropertyType(String propertyType) { + + if (propertyType == null || propertyType.isEmpty()) { + return Either.left(false); + } + + ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(propertyType); + if (toscaPropertyType == null) { + Either definedInDataTypes = isDefinedInDataTypes(propertyType); + return definedInDataTypes; + } else { + return Either.left(true); + } + } + + private Either isDefinedInDataTypes(String propertyType) { + + String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType); + Either dataTypeByUid = getDataTypeByUid(dataTypeUid); + if (dataTypeByUid.isRight()) { + TitanOperationStatus status = dataTypeByUid.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.left(false); + } + return Either.right(status); + } + + return Either.left(true); + + } + + private Either getExternalDataType(String propertyType) { + + String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType); + Either dataTypeByUid = getDataTypeByUid(dataTypeUid); + if (dataTypeByUid.isRight()) { + TitanOperationStatus status = dataTypeByUid.right().value(); + return Either.right(status); + } + + return Either.left(dataTypeByUid.left().value()); + + } + + public Either, TitanOperationStatus> getAllDataTypes() { + + Map dataTypes = new HashMap<>(); + Either, TitanOperationStatus> result = Either.left(dataTypes); + + Either, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class); + if (getAllDataTypes.isRight()) { + TitanOperationStatus status = getAllDataTypes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } else { + return result; + } + } + + List list = getAllDataTypes.left().value(); + if (list != null) { + + log.trace("Number of data types to load is " + list.size()); + + List collect = list.stream().map(p -> p.getDataTypeDataDefinition().getName()).collect(Collectors.toList()); + log.trace("The data types to load are " + collect); + + for (DataTypeData dataTypeData : list) { + + log.trace("Going to fetch data type " + dataTypeData.getDataTypeDataDefinition().getName() + ". uid is " + dataTypeData.getUniqueId()); + Either dataTypeByUid = this.getAndAddDataTypeByUid(dataTypeData.getUniqueId(), dataTypes); + if (dataTypeByUid.isRight()) { + TitanOperationStatus status = dataTypeByUid.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + } + } + + if (log.isTraceEnabled()) { + if (result.isRight()) { + log.trace("After fetching all data types " + result); + } else { + Map map = result.left().value(); + if (map != null) { + String types = map.keySet().stream().collect(Collectors.joining(",", "[", "]")); + log.trace("After fetching all data types " + types); + } + } + } + + return result; + } + + /** + * Build Data type object from graph by unique id + * + * @param uniqueId + * @return + */ + public Either getAndAddDataTypeByUid(String uniqueId, Map allDataTypes) { + + Either result = null; + + if (allDataTypes.containsKey(uniqueId)) { + return Either.left(allDataTypes.get(uniqueId)); + } + + Either dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class); + + if (dataTypesRes.isRight()) { + TitanOperationStatus status = dataTypesRes.right().value(); + log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status); + return Either.right(status); + } + + DataTypeData ctData = dataTypesRes.left().value(); + DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of data type " + uniqueId); + return Either.right(propertiesStatus); + } + + allDataTypes.put(dataTypeDefinition.getName(), dataTypeDefinition); + + String derivedFrom = dataTypeDefinition.getDerivedFromName(); + if (allDataTypes.containsKey(derivedFrom)) { + DataTypeDefinition parentDataTypeDefinition = allDataTypes.get(derivedFrom); + + dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition); + + return Either.left(dataTypeDefinition); + } + + Either, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType, + DataTypeData.class); + log.debug("After retrieving DERIVED_FROM node of " + uniqueId + ". status is " + parentNode); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the parent data type of data type " + uniqueId + ". status is " + titanOperationStatus); + result = Either.right(titanOperationStatus); + return result; + } + } else { + // derived from node was found + ImmutablePair immutablePair = parentNode.left().value(); + DataTypeData parentCT = immutablePair.getKey(); + + String parentUniqueId = parentCT.getUniqueId(); + Either dataTypeByUid = getDataTypeByUid(parentUniqueId); + + if (dataTypeByUid.isRight()) { + return Either.right(dataTypeByUid.right().value()); + } + + DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value(); + + dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition); + + } + result = Either.left(dataTypeDefinition); + + return result; + } + + public Either getDataTypeUsingName(String name) { + + String uid = UniqueIdBuilder.buildDataTypeUid(name); + + Either dataTypeByUid = getDataTypeByUid(uid); + + return dataTypeByUid; + } + + public Either checkInnerType(PropertyDataDefinition propDataDef) { + + String propertyType = propDataDef.getType(); + + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + Either result = getInnerType(type, () -> propDataDef.getSchema()); + + return result; + } + + public Either, TitanOperationStatus> getAllDataTypeNodes() { + Either, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class); + if (getAllDataTypes.isRight()) { + TitanOperationStatus status = getAllDataTypes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + return Either.right(status); + } + } + return getAllDataTypes; + } + + public Either validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map dataTypes) { + log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value); + ToscaPropertyType type = getType(propertyType); + + if (isValidate) { + + if (type == null) { + DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType); + ImmutablePair validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes); + if (validateResult.right.booleanValue() == false) { + log.debug("The value {} of property from type {} is invalid", value, propertyType); + return Either.right(false); + } + JsonElement jsonElement = validateResult.left; + String valueFromJsonElement = getValueFromJsonElement(jsonElement); + return Either.left(valueFromJsonElement); + } + log.trace("before validating property type {}", propertyType); + boolean isValidProperty = isValidValue(type, value, innerType, dataTypes); + if (false == isValidProperty) { + log.debug("The value {} of property from type {} is invalid", value, type); + return Either.right(false); + } + } + Object convertedValue = value; + if (false == isEmptyValue(value) && isValidate) { + PropertyValueConverter converter = type.getConverter(); + convertedValue = converter.convert(value, innerType, dataTypes); + } + return Either.left(convertedValue); + } + + public Either validateAndUpdatePropertyValue(String propertyType, String value, String innerType, Map dataTypes) { + return validateAndUpdatePropertyValue(propertyType, value, true, innerType, dataTypes); + } + + /* + * @Override public PropertyOperation getPropertyOperation() { return this; } + */ + protected TitanOperationStatus fillProperties(String uniqueId, Consumer> propertySetter) { + Either, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.GroupType, uniqueId); + if (findPropertiesOfNode.isRight()) { + TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value(); + log.debug("After looking for properties of vertex " + uniqueId + ". status is " + titanOperationStatus); + if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) { + return TitanOperationStatus.OK; + } else { + return titanOperationStatus; + } + } else { + Map properties = findPropertiesOfNode.left().value(); + + if (properties != null) { + List propertiesAsList = properties.entrySet().stream().map(p -> p.getValue()).collect(Collectors.toList()); + propertySetter.accept(propertiesAsList); + } + + return TitanOperationStatus.OK; + } + } + + /** + * add properties to element type. + * + * Per property, add a property node and associate it to the element type + * + * @param uniqueId + * @param propertiesMap + * TODO + * @return + */ + protected Either, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map propertiesMap) { + + Map propertiesData = new HashMap(); + + if (propertiesMap != null) { + + for (Entry propertyDefinitionEntry : propertiesMap.entrySet()) { + String propertyName = propertyDefinitionEntry.getKey(); + + Either addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId); + + if (addPropertyToNodeType.isRight()) { + TitanOperationStatus operationStatus = addPropertyToNodeType.right().value(); + log.error("Failed to associate " + nodeType.getName() + " " + uniqueId + " to property " + propertyName + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + propertiesData.put(propertyName, addPropertyToNodeType.left().value()); + + } + } + + return Either.left(propertiesData); + + } + + protected TitanOperationStatus addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map propertiesMap, TitanVertex elementVertex) { + + if (propertiesMap != null) { + + for (Entry propertyDefinitionEntry : propertiesMap.entrySet()) { + String propertyName = propertyDefinitionEntry.getKey(); + + TitanOperationStatus operationStatus = this.addPropertyToNodeType(elementVertex, propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId); + + if (!operationStatus.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate {} {} to property {} in graph. status is {}", nodeType.getName(), uniqueId, propertyName, operationStatus); + return operationStatus; + } + } + } + + return TitanOperationStatus.OK; + + } + + public Either, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum elementType, List properties) { + + Map propMap; + if (properties == null) { + propMap = null; + } else { + propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef)); + } + return addPropertiesToElementType(uniqueId, elementType, propMap); + } + + public TitanOperationStatus addPropertiesToElementType(TitanVertex elementVertex, String uniqueId, NodeTypeEnum elementType, List properties) { + + Map propMap; + if (properties == null) { + propMap = null; + } else { + propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef)); + } + return addPropertiesToElementType(uniqueId, elementType, propMap, elementVertex); + } + + @Override + public Either updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition) { + return updateDataType(newDataTypeDefinition, oldDataTypeDefinition, true); + } + + @Override + public Either updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition, boolean inTransaction) { + + Either result = null; + + try { + + List newProperties = newDataTypeDefinition.getProperties(); + + List oldProperties = oldDataTypeDefinition.getProperties(); + + String newDerivedFromName = getDerivedFromName(newDataTypeDefinition); + + String oldDerivedFromName = getDerivedFromName(oldDataTypeDefinition); + + String dataTypeName = newDataTypeDefinition.getName(); + + List propertiesToAdd = new ArrayList<>(); + if (isPropertyOmitted(newProperties, oldProperties, dataTypeName) || isPropertyTypeChanged(dataTypeName, newProperties, oldProperties, propertiesToAdd) || isDerivedFromNameChanged(dataTypeName, newDerivedFromName, oldDerivedFromName)) { + + log.debug("The new data type " + dataTypeName + " is invalid."); + + result = Either.right(StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY); + return result; + } + + if (propertiesToAdd == null || propertiesToAdd.isEmpty()) { + log.debug("No new properties has been defined in the new data type " + newDataTypeDefinition); + result = Either.right(StorageOperationStatus.OK); + return result; + } + + Either, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(oldDataTypeDefinition.getUniqueId(), propertiesToAdd); + + if (addPropertiesToDataType.isRight()) { + log.debug("Failed to update data type {} to Graph. Status is {}", oldDataTypeDefinition, addPropertiesToDataType.right().value().name()); + BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("UpdateDataType", "Property"); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToDataType.right().value())); + return result; + } else { + + Either dataTypeByUid = this.getDataTypeByUid(oldDataTypeDefinition.getUniqueId()); + if (dataTypeByUid.isRight()) { + TitanOperationStatus status = addPropertiesToDataType.right().value(); + log.debug("Failed to get data type {} after update. Status is {}", oldDataTypeDefinition.getUniqueId(), status.name()); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("UpdateDataType", "Property", status.name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + result = Either.left(dataTypeByUid.left().value()); + } + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private String getDerivedFromName(DataTypeDefinition dataTypeDefinition) { + String derivedFromName = dataTypeDefinition.getDerivedFromName(); + // if (derivedFromName == null) { + // DataTypeDefinition derivedFrom = dataTypeDefinition.getDerivedFrom(); + // if (derivedFrom != null) { + // log.debug("Dervied from is taken from definition"); + // derivedFromName = derivedFrom.getName(); + // } + // } else { + // log.debug("Dervied from is taken from field derivedFromName"); + // } + return derivedFromName; + } + + private boolean isPropertyTypeChanged(String dataTypeName, List newProperties, List oldProperties, List outputPropertiesToAdd) { + + if (newProperties != null && oldProperties != null) { + + Map newPropsMapper = newProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p)); + Map oldPropsMapper = oldProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p)); + + for (Entry newPropertyEntry : newPropsMapper.entrySet()) { + + String propName = newPropertyEntry.getKey(); + PropertyDefinition propDef = newPropertyEntry.getValue(); + + PropertyDefinition oldPropertyDefinition = oldPropsMapper.get(propName); + if (oldPropertyDefinition == null) { + log.debug("New property {} received in the data type {}", propName, dataTypeName); + outputPropertiesToAdd.add(propDef); + continue; + } + + String oldType = oldPropertyDefinition.getType(); + String oldEntryType = getEntryType(oldPropertyDefinition); + + String newType = propDef.getType(); + String newEntryType = getEntryType(propDef); + + if (false == oldType.equals(newType)) { + log.debug("Existing property {} in data type {} has a differnet type {} than the new one {}", propName, dataTypeName, oldType, newType); + return true; + } + + if (false == equalsEntryTypes(oldEntryType, newEntryType)) { + log.debug("Existing property {} in data type {} has a differnet entry type {} than the new one {}", propName, dataTypeName, oldEntryType, newEntryType); + return true; + } + + } + + } + + return false; + } + + private boolean equalsEntryTypes(String oldEntryType, String newEntryType) { + + if (oldEntryType == null && newEntryType == null) { + return true; + } else if (oldEntryType != null && newEntryType != null) { + return oldEntryType.equals(newEntryType); + } else { + return false; + } + } + + private String getEntryType(PropertyDefinition oldPropertyDefinition) { + String entryType = null; + SchemaDefinition schema = oldPropertyDefinition.getSchema(); + if (schema != null) { + PropertyDataDefinition schemaProperty = schema.getProperty(); + if (schemaProperty != null) { + entryType = schemaProperty.getType(); + } + } + return entryType; + } + + private boolean isPropertyOmitted(List newProperties, List oldProperties, String dataTypeName) { + + boolean isValid = validateChangeInCaseOfEmptyProperties(newProperties, oldProperties, dataTypeName); + if (false == isValid) { + log.debug("At least one property is missing in the new data type {}", dataTypeName); + return false; + } + + if (newProperties != null && oldProperties != null) { + + List newProps = newProperties.stream().map(p -> p.getName()).collect(Collectors.toList()); + List oldProps = oldProperties.stream().map(p -> p.getName()).collect(Collectors.toList()); + + if (false == newProps.containsAll(oldProps)) { + StringJoiner joiner = new StringJoiner(",", "[", "]"); + newProps.forEach(p -> joiner.add(p)); + log.debug("Properties {} in data type {} are missing, but they already defined in the existing data type", joiner.toString(), dataTypeName); + return true; + } + + } + return false; + } + + private boolean validateChangeInCaseOfEmptyProperties(List newProperties, List oldProperties, String dataTypeName) { + + if (newProperties != null) { + if (newProperties.isEmpty()) { + newProperties = null; + } + } + + if (oldProperties != null) { + if (oldProperties.isEmpty()) { + oldProperties = null; + } + } + + if ((newProperties == null && oldProperties == null) || (newProperties != null && oldProperties != null)) { + return true; + } + + return false; + } + + private boolean isDerivedFromNameChanged(String dataTypeName, String newDerivedFromName, String oldDerivedFromName) { + + if (newDerivedFromName != null) { + boolean isEqual = newDerivedFromName.equals(oldDerivedFromName); + if (false == isEqual) { + log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName); + } + return !isEqual; + } else if (oldDerivedFromName == null) { + return false; + } else {// new=null, old != null + log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName); + return true; + } + + } + + /** + * + * Future - unfinished + * + * @param type + * @param value + * @return + */ + public boolean isValueToscaFunction(String type, String value) { + + boolean result = false; + + if (ToscaPropertyType.STRING.getType().equals(type) || isScalarDerivedFromString(type)) { + + } + + String[] functions = { "get_input" }; + + if (value != null) { + + for (String function : functions) { + + } + + } + + return result; + + } + + /** + * Future - unfinished + * + * @param type + * @return + */ + private boolean isScalarDerivedFromString(String type) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java new file mode 100644 index 0000000000..e8892ad333 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java @@ -0,0 +1,1674 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +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 com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +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.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.CapabiltyInstance; +import org.openecomp.sdc.be.model.Point; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.RequirementImplDef; +import org.openecomp.sdc.be.model.operations.api.IRequirementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.CapabilityTypeData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.resources.data.RequirementImplData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("requirement-operation") +public class RequirementOperation implements IRequirementOperation { + + private static final String NA = "NA"; + + private static final String EQUAL_SIGN = "="; + + private static final String EMPTY_STRING = ""; + + public RequirementOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(RequirementOperation.class.getName()); + + @javax.annotation.Resource + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource + private CapabilityTypeOperation capabilityTypeOperation; + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) { + log.debug("The object returned after create capability is " + capabilityTypeData); + + CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition( + capabilityTypeData.getCapabilityTypeDataDefinition()); + + return capabilityTypeDefResult; + } + + /** + * FOR TEST ONLY + * + * @param capabilityOperation + */ + public void setCapabilityOperation(CapabilityOperation capabilityOperation) { + this.capabilityOperation = capabilityOperation; + } + + public void setCapabilityTypeOperation(CapabilityTypeOperation capabilityTypeOperation) { + this.capabilityTypeOperation = capabilityTypeOperation; + } + + @Override + public Either addRequirementToResource(String reqName, + RequirementDefinition reqDefinition, String resourceId) { + + return addRequirementToResource(reqName, reqDefinition, resourceId, false); + } + + private Either associateRequirementToRelationshipType(RequirementData reqData, + RequirementDefinition reqDefinition) { + + String relationship = reqDefinition.getRelationship(); + + if (relationship == null) { + log.debug("The provided relationship is null."); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.RelationshipType, relationship); + Either createRelation = titanGenericDao.createRelation(reqData, + uniqueIdData, GraphEdgeLabels.RELATIONSHIP_TYPE, null); + + return createRelation; + + } + + /** + * Associate the requirement node to its capability type + * + * @param reqData + * @param reqDefinition + * @return + */ + private Either associateRequirementToCapabilityType(RequirementData reqData, + RequirementDefinition reqDefinition) { + + String capability = reqDefinition.getCapability(); + + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, capability); + Either createRelation = titanGenericDao.createRelation(reqData, + uniqueIdData, GraphEdgeLabels.CAPABILITY_TYPE, null); + + log.debug("After associating requirementData " + reqData + " to capability " + capability + ". status is " + + createRelation); + + return createRelation; + } + + private TitanOperationStatus associateRequirementToCapabilityType(TitanVertex reqData, + RequirementDefinition reqDefinition) { + + String capability = reqDefinition.getCapability(); + + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, capability); + TitanOperationStatus createRelation = titanGenericDao.createEdge(reqData, uniqueIdData, + GraphEdgeLabels.CAPABILITY_TYPE, null); + + log.debug("After associating requirementData {} to capability {}. status is {}" + reqData, capability, + createRelation); + + return createRelation; + } + + /** + * Associate requirement impl node to capability instance node + * + * @param reqImplData + * @param capabilityInstData + * @param capabilityName + * @return + */ + private Either associateRequirementImplToCapabilityInst( + RequirementImplData reqImplData, CapabilityInstData capabilityInstData, String capabilityName) { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + + log.debug( + "Before associating requirement impl " + reqImplData + " to capability instance " + capabilityInstData); + Either createRelation = titanGenericDao.createRelation(reqImplData, + capabilityInstData, GraphEdgeLabels.CAPABILITY_INST, props); + log.debug("After associating requirement impl " + reqImplData + " to capability instance " + capabilityInstData + + ".status is " + createRelation); + + return createRelation; + + } + + /** + * Add requirement node to graph + * + * @param resourceId + * @param reqName + * @param reqDefinition + * @return + */ + private Either addRequirementData(String resourceId, String reqName, + RequirementDefinition reqDefinition) { + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + + RequirementData requirementData = buildRequirementData(resourceId, reqName, reqDefinition); + + log.debug("Before adding requirement data to graph {}", requirementData); + Either createNodeResult = titanGenericDao.createNode(requirementData, + RequirementData.class); + + log.debug("After adding requirement to graph {}", requirementData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add requirement " + reqName + " [ " + requirementData + " ] " + " to graph. status is " + + operationStatus); + return Either.right(operationStatus); + } + + TitanOperationStatus status = associateResourceDataToRequirementData(resourceId, reqName, resourceData, + requirementData); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + return Either.left(createNodeResult.left().value()); + + } + + private Either addRequirementData(TitanVertex vertex, String resourceId, + String reqName, RequirementDefinition reqDefinition) { + + RequirementData requirementData = buildRequirementData(resourceId, reqName, reqDefinition); + + log.debug("Before adding requirement data to graph {}", requirementData); + Either createNodeResult = titanGenericDao.createNode(requirementData); + + log.debug("After adding requirement to graph {}", requirementData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add requirement " + reqName + " [ " + requirementData + " ] " + " to graph. status is " + + operationStatus); + return Either.right(operationStatus); + } + + TitanOperationStatus status = associateResourceDataToRequirementData(resourceId, reqName, vertex, + createNodeResult.left().value()); + if (!status.equals(TitanOperationStatus.OK)) { + return Either.right(status); + } + return Either.left(createNodeResult.left().value()); + } + + /** + * Asssociate resource node to requirement node with REQUIREMENT label and + * requirement name as property on the edge. + * + * @param resourceId + * @param reqName + * @param resourceData + * @param requirementData + * @return + */ + private TitanOperationStatus associateResourceDataToRequirementData(String resourceId, String reqName, + ResourceMetadataData resourceData, RequirementData requirementData) { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName); + Either createRelResult = titanGenericDao.createRelation(resourceData, + requirementData, GraphEdgeLabels.REQUIREMENT, props); + log.debug("After creatin edge between resource " + resourceId + " to requirement " + requirementData); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate resource " + resourceId + " to requirement " + reqName + "[ " + + requirementData + "] in graph. status is " + operationStatus); + } + return TitanOperationStatus.OK; + } + + private TitanOperationStatus associateResourceDataToRequirementData(String resourceId, String reqName, + TitanVertex resourceVertex, TitanVertex requirementVertex) { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(resourceVertex, requirementVertex, + GraphEdgeLabels.REQUIREMENT, props); + log.debug("After creatin edge between resource {} to requirement {}", resourceId, requirementVertex); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to requirement {} in graph. status is " + resourceId, reqName, + createRelResult); + } + return TitanOperationStatus.OK; + } + + private RequirementData buildRequirementData(String resourceId, String reqName, + RequirementDefinition reqDefinition) { + + RequirementData requirementData = new RequirementData(); + requirementData.setNode(reqDefinition.getNode()); + requirementData.setUniqueId(UniqueIdBuilder.buildRequirementUid(resourceId, reqName)); + Long creationTime = System.currentTimeMillis(); + requirementData.setCreationTime(creationTime); + requirementData.setModificationTime(creationTime); + requirementData.setRelationshipType(reqDefinition.getRelationship()); + requirementData.setMinOccurrences(reqDefinition.getMinOccurrences()); + requirementData.setMaxOccurrences(reqDefinition.getMaxOccurrences()); + + return requirementData; + } + + /** + * build requirement impl node associate it to resource, requirement & + * implementation resource + * + * [RESOURCE] --> [REQUIREMENT IMPL] --> [ RESOURCE IMPL ] | V [REQUIREMENT] + * + * @param resourceLabel + * @param resourceId + * @param reqName + * @param requirementUid + * @param reqImplDefinition + * @return + */ + private Either addRequirementImplData(NodeTypeEnum resourceLabel, + String resourceId, String reqName, String requirementUid, RequirementImplDef reqImplDefinition) { + + RequirementImplData requirementImplData = buildRequirementImplData(resourceId, reqName, reqImplDefinition); + + log.debug("Before adding requirement impl data to graph " + requirementImplData); + Either createNodeResult = titanGenericDao + .createNode(requirementImplData, RequirementImplData.class); + log.debug("After adding requirement to graph " + requirementImplData + ". status is " + createNodeResult); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add requirement " + reqName + " [ " + requirementImplData + " ] " + + " to graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + Either createRelResult = associateReqImplRoResource(resourceLabel, + resourceId, reqName, requirementImplData); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate resource " + resourceId + " to requirement impl " + requirementImplData + + "[ " + requirementImplData + "] in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + Either associateToResourceImpl = associateReqImplToImplResource( + requirementImplData, reqImplDefinition.getNodeId()); + if (associateToResourceImpl.isRight()) { + TitanOperationStatus operationStatus = associateToResourceImpl.right().value(); + log.error("Failed to associate requirement impl " + requirementImplData + " to resource impl " + + reqImplDefinition.getNodeId() + "[ " + requirementImplData + "] in graph. status is " + + operationStatus); + return Either.right(operationStatus); + } + + Either associateToRequirement = associateReqImplToRequirement( + requirementImplData, requirementUid); + if (associateToRequirement.isRight()) { + TitanOperationStatus operationStatus = associateToRequirement.right().value(); + log.error("Failed to associate requirement impl " + requirementImplData + " to requirement " + reqName + + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + private RequirementImplData buildRequirementImplData(String resourceId, String reqName, + RequirementImplDef reqImplDefinition) { + String reqImplUid = UniqueIdBuilder.buildRequirementImplUid(resourceId, reqName); + RequirementImplData requirementImplData = new RequirementImplData(); + requirementImplData.setName(reqName); + requirementImplData.setUniqueId(reqImplUid); + Long creationTime = System.currentTimeMillis(); + requirementImplData.setCreationTime(creationTime); + requirementImplData.setModificationTime(creationTime); + Point point = reqImplDefinition.getPoint(); + if (point != null) { + requirementImplData.setPosX(point.getX()); + requirementImplData.setPosY(point.getY()); + } + return requirementImplData; + } + + /** + * associate requirement impl node to the source requirement. The source + * requirement maybe belongs to one of parents. + * + * @param requirementImplData + * @param requirementUid + * @return + */ + private Either associateReqImplToRequirement( + RequirementImplData requirementImplData, String requirementUid) { + + UniqueIdData to = new UniqueIdData(NodeTypeEnum.Requirement, requirementUid); + log.debug("Before creating edge between requirement impl " + requirementImplData + " to requirement " + + requirementUid); + Either createRelResult = titanGenericDao + .createRelation(requirementImplData, to, GraphEdgeLabels.IMPLEMENTATION_OF, null); + log.debug("Before creating edge between requirement impl " + requirementImplData + " to requirement " + + requirementUid + ". status is " + createRelResult); + + return createRelResult; + } + + /** + * Associate requirement impl node to the node which supply this + * requirement. + * + * @param requirementImplData + * @param nodeId + * @return + */ + private Either associateReqImplToImplResource( + RequirementImplData requirementImplData, String nodeId) { + + UniqueIdData nodeImpl = new UniqueIdData(NodeTypeEnum.Resource, nodeId); + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), nodeId); + log.debug("Before creating edge between requirement impl " + requirementImplData + " to node impl " + nodeId); + Either createRelResult = titanGenericDao + .createRelation(requirementImplData, nodeImpl, GraphEdgeLabels.NODE_IMPL, props); + log.debug("After creating edge between requirement " + requirementImplData + " to node impl " + nodeId + + ". status is " + createRelResult); + + return createRelResult; + } + + /** + * create an edge between the requirement impl node to the implementation + * resource. + * + * @param resourceLabel + * @param resourceId + * @param reqName + * @param requirementImplData + * @return + */ + private Either associateReqImplRoResource(NodeTypeEnum resourceLabel, + String resourceId, String reqName, RequirementImplData requirementImplData) { + + UniqueIdData resource = new UniqueIdData(resourceLabel, resourceId); + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName); + log.debug( + "Before creating edge between resource " + resourceId + " to requirement impl " + requirementImplData); + Either createRelResult = titanGenericDao.createRelation(resource, + requirementImplData, GraphEdgeLabels.REQUIREMENT_IMPL, props); + log.debug("After creating edge between to requirement impl " + requirementImplData + " to resource " + resource + + ". status is " + createRelResult); + + return createRelResult; + } + + private void validateNodeExists(String node) { + // TODO Auto-generated method stub + + } + + @Override + public Either addRequirementToResource(String reqName, + RequirementDefinition reqDefinition, String resourceId, boolean inTransaction) { + + Either result = null; + try { + + log.debug("Going to add requirement " + reqName + " to resource " + resourceId + + ". requirement definition is " + reqDefinition); + + validateNodeExists(reqDefinition.getNode()); + + // 1. add requirement node in graph and associate it to the resource + log.debug("Going to add requirement node in graph and associate it to the resource"); + Either addRequirementData = addRequirementData(resourceId, reqName, + reqDefinition); + if (addRequirementData.isRight()) { + log.error("Failed to add requirement " + reqName + " node to graph. status is " + addRequirementData); + result = Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(addRequirementData.right().value())); + return result; + } + + RequirementData requirementData = addRequirementData.left().value(); + + log.debug("Going to associate the requirement to the appriopriate capability type"); + Either associateReqToCapabilityType = associateRequirementToCapabilityType( + requirementData, reqDefinition); + if (associateReqToCapabilityType.isRight()) { + log.error("Failed to associate requirement data node " + requirementData + + " to the capability type node " + reqDefinition.getCapability()); + result = Either.right(DaoStatusConverter + .convertTitanStatusToStorageStatus(associateReqToCapabilityType.right().value())); + return result; + } + + // TODO: esofer associate requirement to the relationship type + /* + * Either + * associateReqToRelshipType = + * associateRequirementToRelationshipType( requirementData, + * reqDefinition); + * + * if (associateReqToRelshipType.isRight() && + * associateReqToRelshipType.right().value() != + * TitanOperationStatus.NOT_FOUND) { + * log.error("Failed to associate requirement data node " + + * requirementData + " to the relationship type node " + + * reqDefinition.getRelationship()); result = Either + * .right(TitanStatusConverter + * .convertTitanStatusToStorageStatus(associateReqToRelshipType + * .right().value())); return result; } + */ + + log.debug("Going to fetch the requirement " + reqName + " from graph"); + Either requirementDefinitionRes = getRequirement( + requirementData.getUniqueId()); + if (requirementDefinitionRes.isRight()) { + result = Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(requirementDefinitionRes.right().value())); + return result; + } + + result = Either.left(requirementDefinitionRes.left().value()); + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public StorageOperationStatus addRequirementToResource(TitanVertex metadataVertex, String reqName, + RequirementDefinition reqDefinition, String resourceId, boolean inTransaction) { + + StorageOperationStatus result = StorageOperationStatus.OK; + try { + + log.debug("Going to add requirement {} to resource . requirement definition is ", reqName, resourceId, + reqDefinition); + + validateNodeExists(reqDefinition.getNode()); + + // 1. add requirement node in graph and associate it to the resource + log.debug("Going to add requirement node in graph and associate it to the resource"); + Either addRequirementData = addRequirementData(metadataVertex, + resourceId, reqName, reqDefinition); + if (addRequirementData.isRight()) { + log.error("Failed to add requirement {} node to graph. status is {}", reqName, + addRequirementData.right().value()); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(addRequirementData.right().value()); + return result; + } + + log.debug("Going to associate the requirement to the appriopriate capability type"); + TitanOperationStatus associateReqToCapabilityType = associateRequirementToCapabilityType( + addRequirementData.left().value(), reqDefinition); + if (!associateReqToCapabilityType.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate requirement data node {} to the capability type node {}" + reqDefinition, + reqDefinition.getCapability()); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(associateReqToCapabilityType); + return result; + } + return result; + + } finally { + if (false == inTransaction) { + if (result == null || !result.equals(TitanOperationStatus.OK)) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + /** + * Fetch requirement from graph + * + * @param uniqueId + * - the uniqueid of the requirement in the graph + * @return + */ + public Either getRequirement(String uniqueId) { + + log.debug("Going to fetch the requirement {} from graph.", uniqueId); + Either reqDataResult = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), uniqueId, RequirementData.class); + + if (reqDataResult.isRight()) { + log.error("Failed to find requirement node in graph " + uniqueId + ". status is " + reqDataResult); + return Either.right(reqDataResult.right().value()); + } + + log.debug("Going to fetch the capability type associate to requirement {}", uniqueId); + Either, TitanOperationStatus> capabilityTypeRes = titanGenericDao + .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.CAPABILITY_TYPE, + NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + + if (capabilityTypeRes.isRight()) { + log.error("Cannot find the capability of a given requirement " + uniqueId + ". status is " + + capabilityTypeRes); + return Either.right(capabilityTypeRes.right().value()); + } + + ImmutablePair capability = capabilityTypeRes.left().value(); + + String capabilityType = capability.getKey().getCapabilityTypeDataDefinition().getType(); + + // TODO: esofer add relationship as edge + /* + * Either>, + * TitanOperationStatus> relationshipRes = titanGenericDao + * .getChildrenNodes( GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + * uniqueId, GraphEdgeLabels.RELATIONSHIP_TYPE, + * NodeTypeEnum.RelationshipType, RelationshipTypeData.class); + * + * if (relationshipRes.isRight() && relationshipRes.right().value() != + * TitanOperationStatus.NOT_FOUND) { + * log.error("Cannot find the capability of a given requirement " + + * uniqueId + ". status is " + capabilityTypesRes); return + * Either.right(relationshipRes.right().value()); } + * + * String relationshipType = null; if (relationshipRes.isLeft()) { + * List> rstPairs = + * relationshipRes .left().value(); if (rstPairs == null || true == + * rstPairs.isEmpty()) { log.error( + * "Cannot find the capability of a given requirement " + uniqueId); + * return Either.right(TitanOperationStatus.NOT_FOUND); } + * + * ImmutablePair relationship = + * rstPairs .get(0); relationshipType = relationship.getKey().getType(); + * } + */ + + log.debug("Going to fetch the capability type associate to requirement {}", uniqueId); + Either, TitanOperationStatus> parentNode = titanGenericDao + .getParentNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.REQUIREMENT, + NodeTypeEnum.Resource, ResourceMetadataData.class); + if (parentNode.isRight()) { + log.error("Cannot find the parent resource for a given requirement " + uniqueId + ". status is " + + parentNode.right().value()); + return Either.right(parentNode.right().value()); + } + + RequirementData requirementData = reqDataResult.left().value(); + + RequirementDefinition requirementDefinition = new RequirementDefinition(); + requirementDefinition.setOwnerId(parentNode.left().value().getLeft().getMetadataDataDefinition().getUniqueId()); + requirementDefinition.setNode(requirementData.getNode()); + requirementDefinition.setUniqueId(requirementData.getUniqueId()); + requirementDefinition.setCapability(capabilityType); + requirementDefinition.setRelationship(requirementData.getRelationshipType()); + requirementDefinition.setMinOccurrences(requirementData.getMinOccurrences()); + requirementDefinition.setMaxOccurrences(requirementData.getMaxOccurrences()); + + return Either.left(requirementDefinition); + + } + + @Override + public Either getRequirementOfResource(String reqName, + String resourceId) { + + return getRequirementOfResource(reqName, resourceId, false); + } + + @Override + public Either getRequirementOfResource(String reqName, + String resourceId, boolean inTransaction) { + + Either result = null; + + try { + String reqUniqueId = UniqueIdBuilder.buildRequirementUid(resourceId, reqName); + Either requirementRes = getRequirement(reqUniqueId); + + if (requirementRes.isRight()) { + log.debug("Failed to retrieve requirement " + reqName + " associated to resource " + resourceId); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(requirementRes.right().value())); + } else { + result = Either.left(requirementRes.left().value()); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either addRequirementImplToResource(String reqName, + RequirementImplDef reqDefinition, String resourceId, String parentReqUniqueId) { + + return addRequirementImplToResource(reqName, reqDefinition, resourceId, parentReqUniqueId, false); + + } + + @Override + public Either addRequirementImplToResource(String reqName, + RequirementImplDef reqImplDefinition, String resourceId, String parentReqUniqueId, boolean inTransaction) { + + Either result = null; + + try { + + // find the requirement defined at the resource itself or under one + // of its parents + Either findReq = getRequirement(parentReqUniqueId); + log.debug("After looking for requirement " + parentReqUniqueId + ". status is " + findReq); + if (findReq.isRight()) { + TitanOperationStatus status = findReq.right().value(); + log.error("The requirment " + parentReqUniqueId + " was not found in the graph. status is " + + findReq.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + RequirementDefinition reqDefinition = findReq.left().value(); + String reqNode = reqDefinition.getNode(); + String reqCapability = reqDefinition.getCapability(); + + String nodeIdImpl = reqImplDefinition.getNodeId(); + + checkNodeIdImplementsRequirementNode(nodeIdImpl, reqNode); + + Either addRequirementImplData = addRequirementImplData( + NodeTypeEnum.Resource, resourceId, reqName, parentReqUniqueId, reqImplDefinition); + + if (addRequirementImplData.isRight()) { + TitanOperationStatus status = addRequirementImplData.right().value(); + log.error("Failed to add requirement data impl node in the graph. status is " + + addRequirementImplData.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + RequirementImplData requirementImplData = addRequirementImplData.left().value(); + + log.debug("Add the properties of the capabilities of the target node " + nodeIdImpl + + " to the requirement impl node " + requirementImplData.getUniqueId() + " in graph."); + Map requirementPropertiesPerCapability = reqImplDefinition + .getRequirementProperties(); + TitanOperationStatus addPropsResult = addCapabilityPropertiesToReqImpl(requirementImplData, reqCapability, + nodeIdImpl, requirementPropertiesPerCapability); + + if (addPropsResult != TitanOperationStatus.OK) { + log.error("Failed to add capabilities properties to Requirement impl " + requirementImplData); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropsResult)); + return result; + } + + result = Either.left(reqDefinition); + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + return result; + } + + private Either getRequirementImplOfResource(String reqName, + String resourceId) { + + RequirementImplDef requirementImplDef = new RequirementImplDef(); + + Either>, TitanOperationStatus> reqImplNodesRes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.REQUIREMENT_IMPL, NodeTypeEnum.RequirementImpl, RequirementImplData.class); + log.debug("After looking for requirement impl edge of resource " + resourceId); + if (reqImplNodesRes.isRight()) { + TitanOperationStatus status = reqImplNodesRes.right().value(); + return Either.right(status); + } + + boolean found = false; + List> reqImplNodes = reqImplNodesRes.left().value(); + for (ImmutablePair entry : reqImplNodes) { + GraphEdge graphEdge = entry.getValue(); + String edgeType = (String) graphEdge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + if (reqName.equals(edgeType)) { + found = true; + RequirementImplData requirementImplData = entry.getKey(); + + requirementImplDef.setUniqueId(requirementImplData.getUniqueId()); + + Either, TitanOperationStatus> nodeImplRes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RequirementImpl), + requirementImplData.getUniqueId(), GraphEdgeLabels.NODE_IMPL, NodeTypeEnum.Resource, + ResourceMetadataData.class); + + if (nodeImplRes.isRight()) { + TitanOperationStatus status = nodeImplRes.right().value(); + log.debug("No implementation resource was found under requirement impl " + + requirementImplData.getUniqueId() + ". status is " + status); + + return Either.right(status); + } + String nodeImpl = nodeImplRes.left().value().getKey().getMetadataDataDefinition().getUniqueId(); + requirementImplDef.setNodeId(nodeImpl); + + String posX = requirementImplData.getPosX(); + String posY = requirementImplData.getPosY(); + if (posX != null && posY != null) { + Point point = new Point(posX, posY); + requirementImplDef.setPoint(point); + } + + Either>, TitanOperationStatus> capaInstDataRes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RequirementImpl), + requirementImplData.getUniqueId(), GraphEdgeLabels.CAPABILITY_INST, + NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + if (capaInstDataRes.isRight()) { + TitanOperationStatus status = capaInstDataRes.right().value(); + log.debug("No capability instance was found under requirement impl " + + requirementImplData.getUniqueId() + ". status is " + status); + + return Either.right(status); + } + + Map requirementProperties = new HashMap(); + + List> list = capaInstDataRes.left().value(); + for (ImmutablePair capabilityInst : list) { + CapabilityInstData capabilityInstData = capabilityInst.getKey(); + GraphEdge edge = capabilityInst.getValue(); + Map properties = edge.getProperties(); + if (properties == null) { + log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty() + + " on the edge " + edge); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + String capabilityName = (String) properties.get(GraphPropertiesDictionary.NAME.getProperty()); + if (capabilityName == null) { + log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty() + + " on the edge " + edge); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + + // List keyValuePropertiesList = capabilityInstData + // .getProperties(); + // Map actualValues = new HashMap(); + // fillMapFromKeyValueList(keyValuePropertiesList, + // actualValues); + CapabiltyInstance capabiltyInstance = new CapabiltyInstance(); + capabiltyInstance.setUniqueId(capabilityInstData.getUniqueId()); + // capabiltyInstance.setProperties(actualValues); + requirementProperties.put(capabilityName, capabiltyInstance); + + Either>, TitanOperationStatus> propertyValueNodesRes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), + capabilityInstData.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE, + NodeTypeEnum.PropertyValue, PropertyValueData.class); + + if (propertyValueNodesRes.isRight()) { + TitanOperationStatus status = propertyValueNodesRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the property values of capability instance " + capabilityInstData + + ". status is " + status); + return Either.right(status); + } + } else { + List> propertyValueNodes = propertyValueNodesRes + .left().value(); + + if (propertyValueNodes != null) { + + Map actualValues = new HashMap(); + TitanOperationStatus fillPropertiesResult = fillPropertiesMapFromNodes(propertyValueNodes, + actualValues); + + if (fillPropertiesResult != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of capability " + capabilityName); + return Either.right(fillPropertiesResult); + } + + if (false == actualValues.isEmpty()) { + capabiltyInstance.setProperties(actualValues); + } + } + } + + } + + requirementImplDef.setRequirementProperties(requirementProperties); + + break; + } else { + continue; + } + } + + if (false == found) { + log.debug("Cannot find requirement impl under resource " + resourceId); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + return Either.left(requirementImplDef); + } + + private void fillMapFromKeyValueList(List keyValuePropertiesList, Map actualValues) { + + if (keyValuePropertiesList != null) { + for (String keyValue : keyValuePropertiesList) { + int equalSignLocation = keyValue.indexOf(EQUAL_SIGN); + if (equalSignLocation > -1) { + String key = keyValue.substring(0, equalSignLocation); + String value = EMPTY_STRING; + if (equalSignLocation + 1 < keyValue.length()) { + value = keyValue.substring(equalSignLocation + 1); + } + actualValues.put(key, value); + } + } + } + + } + + private TitanOperationStatus fillPropertiesMapFromNodes( + List> propertyValueNodes, Map actualValues) { + if (propertyValueNodes != null) { + for (ImmutablePair propertyValuePair : propertyValueNodes) { + PropertyValueData propertyValueData = propertyValuePair.getKey(); + GraphEdge propertyValueEdge = propertyValuePair.getValue(); + Map propertyEdgeProps = propertyValueEdge.getProperties(); + if (propertyEdgeProps == null) { + log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty() + + " on the edge " + propertyValueEdge); + return TitanOperationStatus.INVALID_ELEMENT; + } + String paramName = (String) propertyEdgeProps.get(GraphPropertiesDictionary.NAME.getProperty()); + if (paramName == null) { + log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty() + + " on the edge " + propertyValueEdge); + return TitanOperationStatus.INVALID_ELEMENT; + } + actualValues.put(paramName, propertyValueData.getValue()); + } + } + return TitanOperationStatus.OK; + } + + private TitanOperationStatus addCapabilityPropertiesToReqImpl(RequirementImplData reqImplData, String reqCapability, + String nodeIdImpl, Map propertiesValuePerCapability) { + + TitanOperationStatus result = null; + + Either>, TitanOperationStatus> allCapabilities = capabilityOperation + .getAllCapabilitiesPairs(nodeIdImpl); + log.trace("Atter looking for the capabilities of resource " + nodeIdImpl + ". result is " + allCapabilities); + if (allCapabilities.isRight()) { + TitanOperationStatus status = allCapabilities.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find capabilities of resource " + nodeIdImpl + ". status is " + status); + return status; + } + } else { + + List> capabilitiesValue = allCapabilities.left().value(); + checkImplNodeContainsReqCapability(reqCapability, capabilitiesValue); + + for (ImmutablePair entry : capabilitiesValue) { + + CapabilityData capabilityData = entry.getKey(); + + GraphEdge graphEdge = entry.getValue(); + + Either capabilityNameResult = findCapabilityName(capabilityData, + graphEdge); + + if (capabilityNameResult.isRight()) { + TitanOperationStatus status = capabilityNameResult.right().value(); + log.error( + "Failed to find capability name from the edge associated to capability " + capabilityData); + return status; + } + + String capabilityName = capabilityNameResult.left().value(); + log.debug("Going to set properties of capability " + capabilityName); + String cabilityDataUid = capabilityData.getUniqueId(); + + Either ctDataResult = capabilityOperation + .getCapabilityTypeOfCapability(cabilityDataUid); + + if (ctDataResult.isRight()) { + log.error("Cannot find capability type of capbility " + cabilityDataUid + ". status is " + + ctDataResult); + TitanOperationStatus status = ctDataResult.right().value(); + return status; + } + + CapabilityTypeData capabilityTypeData = ctDataResult.left().value(); + + Either, TitanOperationStatus> propertiesStatus = findPropertiesOfCapability( + capabilityTypeData); + if (propertiesStatus.isRight()) { + TitanOperationStatus status = propertiesStatus.right().value(); + log.error("Failed to fetch properties definitions from capability. status is " + status); + return status; + } + + Map properties = propertiesStatus.left().value(); + + CapabiltyInstance capabiltyInstance = null; + if (propertiesValuePerCapability != null) { + capabiltyInstance = propertiesValuePerCapability.get(capabilityName); + } + + Either createCapabilityInstanceNode = createCapabilityInstanceNode( + capabilityName, reqImplData); + if (createCapabilityInstanceNode.isRight()) { + TitanOperationStatus status = createCapabilityInstanceNode.right().value(); + log.error("Failed to create capability instance node (" + capabilityName + ") in graph. status is " + + status); + + return status; + } + CapabilityInstData capabilityInstData = createCapabilityInstanceNode.left().value(); + + Either, TitanOperationStatus> instanceProperties = addPropertiesToCapabilityInstance( + properties, capabiltyInstance, capabilityInstData); + + if (instanceProperties.isRight()) { + TitanOperationStatus status = instanceProperties.right().value(); + log.debug("Failed to add properties to capability instance. status is " + status); + return status; + } + + Either associateCapabilityInstToCapabilityType = associateCapabilityInstToCapabilityType( + capabilityInstData, capabilityTypeData); + if (associateCapabilityInstToCapabilityType.isRight()) { + TitanOperationStatus status = associateCapabilityInstToCapabilityType.right().value(); + log.error("Failed to associate capability instance " + capabilityInstData + + " to capability type node " + capabilityTypeData + " in graph. status is " + status); + + return status; + } + + Either associateCapabilityInst = associateRequirementImplToCapabilityInst( + reqImplData, capabilityInstData, capabilityName); + if (associateCapabilityInst.isRight()) { + TitanOperationStatus status = associateCapabilityInst.right().value(); + log.error("Failed to associate requirement impl " + reqImplData + " to capability instance node " + + capabilityInstData + " of capability " + capabilityName + ") in graph. status is " + + status); + + return status; + } + + } + result = TitanOperationStatus.OK; + } + return result; + } + + private Either, TitanOperationStatus> findPropertiesOfCapability( + CapabilityTypeData capabilityTypeData) { + String capabilityTypeUid = capabilityTypeData.getUniqueId(); + + Either capabilityTypeResult = capabilityTypeOperation + .getCapabilityTypeByUid(capabilityTypeUid); + + if (capabilityTypeResult.isRight()) { + log.error("Failed to find capabilityType " + capabilityTypeUid + " in the graph. status is " + + capabilityTypeResult); + return Either.right(capabilityTypeResult.right().value()); + } + + CapabilityTypeDefinition capabilityTypeDef = capabilityTypeResult.left().value(); + Map properties = capabilityTypeDef.getProperties(); + + return Either.left(properties); + } + + private Either findCapabilityName(CapabilityData capabilityData, + GraphEdge graphEdge) { + Map edgeProps = graphEdge.getProperties(); + String capabilityName = (String) edgeProps.get(GraphPropertiesDictionary.NAME.getProperty()); + + if (capabilityName == null) { + log.debug("Cannot find the name of the capability associated to node " + capabilityData); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + return Either.left(capabilityName); + } + + private Either associateCapabilityInstToCapabilityType( + CapabilityInstData capabilityInstData, CapabilityTypeData capabilityTypeData) { + + Either createRelation = titanGenericDao.createRelation(capabilityInstData, + capabilityTypeData, GraphEdgeLabels.INSTANCE_OF, null); + + return createRelation; + + } + + /** + * add property value node with default value of override value and + * associate it to the capability instance node + * + * @param properties + * - properties definition. old also default value + * @param capabilityInstance + * - hold also properties new value(if exists) + * @param capabilityInstData + * - the graph node which we associate the properties value node + * to. + * @return + */ + private Either, TitanOperationStatus> addPropertiesToCapabilityInstance( + Map properties, CapabiltyInstance capabilityInstance, + CapabilityInstData capabilityInstData) { + + List relationsResult = new ArrayList(); + + if (properties != null) { + for (Entry entry : properties.entrySet()) { + + String paramName = entry.getKey(); + + PropertyDefinition propertyDefinition = entry.getValue(); + + String propertyValue = setPropertyValue(capabilityInstance, paramName, propertyDefinition); + + PropertyValueData propertyValueData = buildPropertyValueData(capabilityInstData.getUniqueId(), + paramName, propertyValue); + + log.debug("Before creating property value data node " + propertyValueData + " in graph."); + Either createNode = titanGenericDao + .createNode(propertyValueData, PropertyValueData.class); + log.debug("Before creating property value data node " + propertyValueData + " in graph. status is " + + createNode); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Failed to create property value node in graph " + propertyValueData + ". status is " + + status); + return Either.right(status); + } + + PropertyValueData propertyValueDataCreated = createNode.left().value(); + + Either createRelation = associateCapabilityInstToPropertyValue( + capabilityInstData, paramName, propertyValueDataCreated); + + if (createRelation.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Failed to create relation between capability instance " + + capabilityInstData.getUniqueId() + " to property value " + + propertyValueDataCreated.getUniqueId() + " in graph. status is " + status); + return Either.right(status); + } + + relationsResult.add(createRelation.left().value()); + + } + } + + return Either.left(relationsResult); + } + + private Either associateCapabilityInstToPropertyValue( + CapabilityInstData capabilityInstData, String paramName, PropertyValueData propertyValueDataCreated) { + + Map edgeProps = new HashMap(); + edgeProps.put(GraphPropertiesDictionary.NAME.getProperty(), paramName); + log.debug("Begin creating relation between capability instance " + capabilityInstData + " to property value " + + propertyValueDataCreated + " in graph."); + Either createRelation = titanGenericDao.createRelation(capabilityInstData, + propertyValueDataCreated, GraphEdgeLabels.PROPERTY_VALUE, edgeProps); + log.debug("After creating relation between capability instance " + capabilityInstData + " to property value " + + propertyValueDataCreated + " in graph. status is " + createRelation); + + return createRelation; + } + + private String setPropertyValue(CapabiltyInstance capabilityInstance, String paramName, + PropertyDefinition propertyDefinition) { + String propertyValue = NA; + if (propertyDefinition.getDefaultValue() != null) { + propertyValue = propertyDefinition.getDefaultValue(); + } + Map propertiesValue = null; + if (capabilityInstance != null) { + propertiesValue = capabilityInstance.getProperties(); + if (propertiesValue != null) { + String tmpValue = propertiesValue.get(paramName); + if (tmpValue != null) { + propertyValue = tmpValue; + } + } + } + return propertyValue; + } + + private String buildPropertykeyValue(String paramName, String paramValue) { + return paramName + EQUAL_SIGN + paramValue; + } + + private PropertyValueData buildPropertyValueData(String capabilityInstDataUid, String paramName, + String propertyValue) { + PropertyValueData propertyValueData = new PropertyValueData(); + propertyValueData.setValue(propertyValue); + String uid = UniqueIdBuilder.buildPropertyValueUniqueId(capabilityInstDataUid, paramName); + propertyValueData.setUniqueId(uid); + Long creationDate = System.currentTimeMillis(); + propertyValueData.setCreationTime(creationDate); + propertyValueData.setModificationTime(creationDate); + return propertyValueData; + } + + private Either createCapabilityInstanceNode(String capabilityName, + RequirementImplData reqImplData) { + + CapabilityInstData capabilityInstData = new CapabilityInstData(); + String uniqueId = UniqueIdBuilder.buildCapabilityInstanceUid(reqImplData.getUniqueId(), capabilityName); + + capabilityInstData.setUniqueId(uniqueId); + // capabilityInstData.setProperties(instanceProperties); + Long creationDate = System.currentTimeMillis(); + capabilityInstData.setCreationTime(creationDate); + capabilityInstData.setModificationTime(creationDate); + + log.debug("Before creating capability instance node in graph " + capabilityInstData); + Either createNode = titanGenericDao.createNode(capabilityInstData, + CapabilityInstData.class); + log.debug( + "After creating capability instance node in graph " + capabilityInstData + ". status is " + createNode); + + return createNode; + } + + private void checkNodeIdImplementsRequirementNode(String nodeIdImpl, String reqNode) { + // TODO Auto-generated method stub + + } + + private void checkImplNodeContainsReqCapability(String reqCapability, + List> capabilitiesValue) { + // TODO Auto-generated method stub + + } + + public Either>, StorageOperationStatus> getAllRequirementsOfResourceOnly( + String resourceId, boolean inTransaction) { + + Either>, StorageOperationStatus> result = null; + + try { + + Map requirements = new HashMap(); + Set caseInsensitiveReqNames = new HashSet<>(); + TitanOperationStatus status = findAllRequirementsNonRecursive(resourceId, requirements, + caseInsensitiveReqNames); + + if (status != TitanOperationStatus.OK) { + log.error("Failed to get all requirements of resource " + resourceId + ". status is " + status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + // TODO handle requirementImpl + result = Either.left(convertRequirementMap(requirements, null, null)); + } + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + @Override + public Either, TitanOperationStatus> getResourceRequirements(String resourceId) { + + Either, TitanOperationStatus> result = null; + + Map requirements = new HashMap(); + Set caseInsensitiveReqNames = new HashSet<>(); + + TitanOperationStatus status = findAllRequirementsRecursively(resourceId, requirements, caseInsensitiveReqNames); + if (status != TitanOperationStatus.OK) { + log.error("Failed to get all requirements of resource " + resourceId + ". status is " + status); + return Either.right(status); + } else { + log.debug("The requirements returned for resource {} are {}", resourceId, requirements); + + if (requirements != null) { + for (Entry entry : requirements.entrySet()) { + String reqName = entry.getKey(); + Either reqImplRes = this + .getRequirementImplOfResource(reqName, resourceId); + if (reqImplRes.isRight()) { + + TitanOperationStatus reqImplResStatus = reqImplRes.right().value(); + if (reqImplResStatus == TitanOperationStatus.NOT_FOUND) { + log.debug("Cannot find implementation of requirement {} under resource {}", reqName, + resourceId); + } else { + log.error("Cannot find implementation of requirement {} under resource {}", reqName, + resourceId); + return Either.right(reqImplResStatus); + } + } else { + RequirementDefinition requirementDefinition = entry.getValue(); + // RequirementImplDef requirementImplDef = + // reqImplRes.left().value(); + // requirementDefinition.setRequirementImpl(requirementImplDef); + } + } + } + log.debug("The requirements returned for resource {} after fetching requirement impl are {}", resourceId, + requirements); + + result = Either.left(requirements); + + return result; + } + + } + + @Override + public Either, StorageOperationStatus> getAllResourceRequirements( + String resourceId, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + try { + + Either, TitanOperationStatus> internalResult = getResourceRequirements( + resourceId); + if (internalResult.isRight()) { + TitanOperationStatus status = internalResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to fetch requirements of resource {} . status is {}", resourceId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Map value = internalResult.left().value(); + + result = Either.left(value); + return result; + + // Map requirements = new + // HashMap(); + // TitanOperationStatus status = findAllRequirementsRecursively( + // resourceId, requirements); + // if (status != TitanOperationStatus.OK) { + // log.error("Failed to get all requirements of resource " + // + resourceId + ". status is " + status); + // return Either.right(TitanStatusConverter + // .convertTitanStatusToStorageStatus(status)); + // } else { + // log.debug("The requirements returned for resource " + // + resourceId + " are " + requirements); + // + // if (requirements != null) { + // for (Entry entry : requirements + // .entrySet()) { + // String reqName = entry.getKey(); + // Either reqImplRes = + // this + // .getRequirementImplOfResource(reqName, + // resourceId); + // if (reqImplRes.isRight()) { + // + // TitanOperationStatus reqImplResStatus = reqImplRes + // .right().value(); + // if (reqImplResStatus == TitanOperationStatus.NOT_FOUND) { + // log.warn("Cannot find implementation of requirement " + // + reqName + // + " under resource " + // + resourceId); + // } else { + // log.error("Cannot find implementation of requirement " + // + reqName + // + " under resource " + // + resourceId); + // return Either + // .right(TitanStatusConverter + // .convertTitanStatusToStorageStatus(reqImplResStatus)); + // } + // } else { + // RequirementDefinition requirementDefinition = entry + // .getValue(); + // RequirementImplDef requirementImplDef = reqImplRes + // .left().value(); + // requirementDefinition + // .setRequirementImpl(requirementImplDef); + // } + // } + // } + // log.debug("The requirements returned for resource " + // + resourceId + " after fetching requirement impl are " + // + requirements); + // + // result = Either.left(requirements); + // + // return result; + // } + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either, StorageOperationStatus> getAllResourceRequirements( + String resourceId) { + + return getAllResourceRequirements(resourceId, false); + + } + + public TitanOperationStatus findAllRequirementsRecursively(String resourceId, + Map requirements, Set caseInsensitiveReqNames) { + + TitanOperationStatus nonRecursiveResult = findAllRequirementsNonRecursive(resourceId, requirements, + caseInsensitiveReqNames); + if (!nonRecursiveResult.equals(TitanOperationStatus.OK) + && !nonRecursiveResult.equals(TitanOperationStatus.NOT_FOUND)) { + return nonRecursiveResult; + } + + Either, TitanOperationStatus> parentNodes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (parentNodesStatus == TitanOperationStatus.NOT_FOUND) { + log.debug("Finish to lookup for parnet requirements"); + return TitanOperationStatus.OK; + } else { + log.error("Failed to find parent requirements of resource {} . status is {}", resourceId, + parentNodesStatus); + return parentNodesStatus; + } + } + ImmutablePair parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentReqStatus = findAllRequirementsRecursively(parentUniqueId, requirements, + caseInsensitiveReqNames); + + if (addParentReqStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch all requirements of resource {}", parentUniqueId); + return addParentReqStatus; + } + + return TitanOperationStatus.OK; + } + + private TitanOperationStatus findAllRequirementsNonRecursive(String resourceId, + Map requirements, Set caseInsensitiveReqNames) { + Either>, TitanOperationStatus> requirementNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.REQUIREMENT, NodeTypeEnum.Requirement, RequirementData.class); + + if (requirementNodes.isRight()) { + TitanOperationStatus status = requirementNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return status; + } + } else { + List> requirementList = requirementNodes.left().value(); + if (requirementList != null) { + for (ImmutablePair requirementPair : requirementList) { + String reqUniqueId = requirementPair.getKey().getUniqueId(); + Map edgeProps = requirementPair.getValue().getProperties(); + String reqName = null; + if (edgeProps != null) { + reqName = (String) edgeProps.get(GraphPropertiesDictionary.NAME.getProperty()); + if (reqName == null) { + log.error("The requirement name is missing on the edge of requirement " + reqUniqueId); + return TitanOperationStatus.INVALID_ELEMENT; + } + } else { + log.error("The requirement name is missing on the edge of requirement " + reqUniqueId); + return TitanOperationStatus.INVALID_ELEMENT; + } + Either requirementDefRes = this + .getRequirement(reqUniqueId); + if (requirementDefRes.isRight()) { + TitanOperationStatus status = requirementDefRes.right().value(); + log.error("Failed to get requirement properties of requirement " + reqUniqueId); + return status; + } + + RequirementDefinition requirementDefinition = requirementDefRes.left().value(); + requirementDefinition.setName(reqName); + // US631462 + if (caseInsensitiveReqNames.contains(reqName.toLowerCase())) { + log.debug( + "The requirement {} was already defined in derived resource (case insensitive). Ignore {} from resource {}", + reqName, reqName, resourceId); + } else { + requirements.put(reqName, requirementDefinition); + caseInsensitiveReqNames.add(reqName.toLowerCase()); + } + + } + } + } + return TitanOperationStatus.OK; + } + + public StorageOperationStatus deleteRequirementFromGraph(String requirementId) { + log.debug("Before deleting requirement from graph " + requirementId); + Either deleteNodeStatus = titanGenericDao.deleteNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), requirementId, RequirementData.class); + if (deleteNodeStatus.isRight()) { + log.error("failed to delete requirement with id {}. status={}", requirementId, + deleteNodeStatus.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNodeStatus.right().value()); + } + return StorageOperationStatus.OK; + } + + public Either, StorageOperationStatus> deleteAllRequirements(String resourceId) { + + return getAllResourceRequirements(resourceId, false); + + } + + public Either, StorageOperationStatus> deleteAllRequirements(String resourceId, + boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + try { + Either, TitanOperationStatus> deleteAllRes = deleteAllRequirementsOfResource( + resourceId); + if (deleteAllRes.isRight()) { + TitanOperationStatus status = deleteAllRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to delete requirements of resource " + resourceId + ". status is " + status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Map value = deleteAllRes.left().value(); + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either, TitanOperationStatus> deleteAllRequirementsOfResource( + String resourceId) { + + Map requirements = new HashMap(); + Set caseInsensitiveReqNames = new HashSet<>(); + TitanOperationStatus requirementsRes = findAllRequirementsNonRecursive(resourceId, requirements, + caseInsensitiveReqNames); + if (requirementsRes != TitanOperationStatus.OK) { + return Either.right(requirementsRes); + } + + if (requirements.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + for (Entry entry : requirements.entrySet()) { + RequirementDefinition requirementDefinition = entry.getValue(); + + String requirementUid = requirementDefinition.getUniqueId(); + + Either deleteNodeRes = titanGenericDao.deleteNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), requirementUid, RequirementData.class); + if (deleteNodeRes.isRight()) { + TitanOperationStatus status = deleteNodeRes.right().value(); + log.error("Failed to delete requirement " + requirementUid + " of resource " + resourceId); + return Either.right(status); + } + } + + return Either.left(requirements); + + } + + public Map> convertRequirementMap( + Map requirementMap, String ownerId, String ownerName) { + + Map> typeToRequirementMap = new HashMap>(); + requirementMap.forEach((reqName, requirement) -> { + // requirement.setOwnerId(ownerId); + // requirement.setOwnerName(ownerName); + if (typeToRequirementMap.containsKey(requirement.getCapability())) { + typeToRequirementMap.get(requirement.getCapability()).add(requirement); + } else { + List list = new ArrayList(); + list.add(requirement); + typeToRequirementMap.put(requirement.getCapability(), list); + } + }); + return typeToRequirementMap; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperation.java new file mode 100644 index 0000000000..22c693d8b3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperation.java @@ -0,0 +1,3089 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.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 java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Vertex; +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.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +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.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.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.AttributeDefinition; +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.ComponentInstanceAttribute; +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.GroupDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +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.ResourceMetadataDefinition; +import org.openecomp.sdc.be.model.cache.ComponentCache; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation; +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.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.utils.GraphDeleteUtil; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.TagData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@org.springframework.stereotype.Component("resource-operation") +public class ResourceOperation extends ComponentOperation implements IResourceOperation { + + public ResourceOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(ResourceOperation.class.getName()); + + @javax.annotation.Resource + private PropertyOperation propertyOperation; + + @javax.annotation.Resource + private IAttributeOperation attributeOperation; + + @javax.annotation.Resource + private RequirementOperation requirementOperation; + + @javax.annotation.Resource + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource + private InterfaceLifecycleOperation interfaceLifecycleOperation; + + @javax.annotation.Resource + private IElementOperation elementOperation; + + @javax.annotation.Resource + private IAdditionalInformationOperation addioAdditionalInformationOperation; + + @javax.annotation.Resource + private GroupOperation groupOperation; + + @javax.annotation.Resource + private ComponentCache componentCache; + + private Gson prettyJson = new GsonBuilder().setPrettyPrinting().create(); + + private GraphDeleteUtil graphDeleteUtil = new GraphDeleteUtil(); + + private static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1"); + private static Pattern uuidNormativeNewVersion = Pattern.compile("^\\d{1,}.0"); + + @Override + public Either createResource(Resource resource) { + return createResource(resource, false); + } + + @Override + public Either createResource(Resource resource, boolean inTransaction) { + + Either result = null; + + try { + generateUUID(resource); + + ResourceMetadataData resourceData = getResourceMetaDataFromResource(resource); + String resourceUniqueId = resource.getUniqueId(); + if (resourceUniqueId == null) { + resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceUniqueId); + } + resourceData.getMetadataDataDefinition().setHighestVersion(true); + + String userId = resource.getCreatorUserId(); + + Either findUser = findUserVertex(userId); + + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } + + TitanVertex creatorVertex = findUser.left().value(); + TitanVertex updaterVertex = creatorVertex; + + String updaterUserId = resource.getLastUpdaterUserId(); + if (updaterUserId != null && !updaterUserId.equals(userId)) { + findUser = findUserVertex(updaterUserId); + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } else { + updaterVertex = findUser.left().value(); + } + } + + // get derived from resources + List derivedResources = null; + Either, StorageOperationStatus> derivedResourcesResult = findDerivedResources(resource); + if (derivedResourcesResult.isRight()) { + result = Either.right(derivedResourcesResult.right().value()); + return result; + } else { + derivedResources = derivedResourcesResult.left().value(); + } + + List tags = resource.getTags(); + if (tags != null && false == tags.isEmpty()) { + Either, StorageOperationStatus> tagsResult = createNewTagsList(tags); + if (tagsResult.isRight()) { + result = Either.right(tagsResult.right().value()); + return result; + } + List tagsToCreate = tagsResult.left().value(); + StorageOperationStatus status = createTagNodesOnGraph(tagsToCreate); + if (!status.equals(StorageOperationStatus.OK)) { + result = Either.right(status); + return result; + } + } + + Either createdVertex = titanGenericDao.createNode(resourceData); + if (createdVertex.isRight()) { + TitanOperationStatus status = createdVertex.right().value(); + log.error("Error returned after creating resource data node {}. status returned is ", resourceData, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + TitanVertex metadataVertex = createdVertex.left().value(); + + TitanOperationStatus associateMetadata = associateMetadataToResource(resourceData, creatorVertex, updaterVertex, derivedResources, metadataVertex); + if (associateMetadata != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateMetadata)); + return result; + } + StorageOperationStatus associateCategory = assosiateMetadataToCategory(resource, resourceData); + if (associateCategory != StorageOperationStatus.OK) { + result = Either.right(associateCategory); + return result; + } + + TitanOperationStatus associateProperties = associatePropertiesToResource(metadataVertex, resourceUniqueId, resource.getProperties()); + if (associateProperties != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateProperties)); + return result; + } + + TitanOperationStatus associateAttributes = associateAttributesToResource(metadataVertex, resource.getAttributes(), resourceUniqueId); + if (associateAttributes != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateAttributes)); + return result; + } + + TitanOperationStatus associateInputs = associateInputsToComponent(metadataVertex, resourceUniqueId, resource.getInputs()); + if (associateInputs != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateInputs)); + return result; + } + + StorageOperationStatus associateRequirements = associateRequirementsToResource(metadataVertex, resourceUniqueId, resource.getRequirements()); + if (associateRequirements != StorageOperationStatus.OK) { + result = Either.right(associateRequirements); + return result; + } + + StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(metadataVertex, resourceUniqueId, resource.getCapabilities()); + if (associateCapabilities != StorageOperationStatus.OK) { + result = Either.right(associateCapabilities); + return result; + } + + StorageOperationStatus associateInterfaces = associateInterfacesToResource(resourceData, resource.getInterfaces(), metadataVertex); + if (associateInterfaces != StorageOperationStatus.OK) { + result = Either.right(associateInterfaces); + return result; + } + + Map resourceArtifacts = resource.getArtifacts(); + Map deploymentArtifacts = resource.getDeploymentArtifacts(); + Map toscaArtifacts = resource.getToscaArtifacts(); + if (resourceArtifacts != null) { + if (deploymentArtifacts != null) { + resourceArtifacts.putAll(deploymentArtifacts); + } + } else { + resourceArtifacts = deploymentArtifacts; + } + if (toscaArtifacts != null) { + if (resourceArtifacts != null) { + resourceArtifacts.putAll(toscaArtifacts); + } else { + resourceArtifacts = toscaArtifacts; + } + } + + StorageOperationStatus associateArtifacts = associateArtifactsToResource(metadataVertex, resourceUniqueId, resourceArtifacts); + if (associateArtifacts != StorageOperationStatus.OK) { + result = Either.right(associateArtifacts); + return result; + } + + List additionalInformation = resource.getAdditionalInformation(); + StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(metadataVertex, resourceUniqueId, additionalInformation); + if (addAdditionalInformation != StorageOperationStatus.OK) { + result = Either.right(addAdditionalInformation); + return result; + } + + result = this.getResource(resourceUniqueId, true); + if (result.isRight()) { + log.error("Cannot get full resource from the graph. status is " + result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Resource retrieved is " + json); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus assosiateMetadataToCategory(Resource resource, ResourceMetadataData resourceData) { + // get category + String categoryName = resource.getCategories().get(0).getName(); + String subcategoryName = resource.getCategories().get(0).getSubcategories().get(0).getName(); + + CategoryData categoryData = null; + Either categoryResult = elementOperation.getNewCategoryData(categoryName, NodeTypeEnum.ResourceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + StorageOperationStatus status = categoryResult.right().value(); + log.error("Cannot find category " + categoryName + " in the graph. status is " + status); + return categoryResult.right().value(); + } + categoryData = categoryResult.left().value(); + if (categoryData != null) { + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), (String) categoryData.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceSubcategory, SubCategoryData.class); + if (childrenNodes.isRight()) { + log.debug("Faield to fetch sub categories for resource category" + categoryData.getCategoryDataDefinition().getName()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(childrenNodes.right().value()); + } + for (ImmutablePair pair : childrenNodes.left().value()) { + SubCategoryData subcategoryData = pair.left; + if (subcategoryData.getSubCategoryDataDefinition().getName().equals(subcategoryName)) { + Either result = titanGenericDao.createRelation(resourceData, subcategoryData, GraphEdgeLabels.CATEGORY, null); + log.debug("After associating resource " + resourceData.getUniqueId() + " to subcategory " + subcategoryData + ". Edge type is " + GraphEdgeLabels.CATEGORY); + if (result.isRight()) { + log.error("Faield to associate resource " + resourceData.getUniqueId() + " to category " + categoryData + ". Edge type is " + GraphEdgeLabels.CATEGORY); + return DaoStatusConverter.convertTitanStatusToStorageStatus(result.right().value()); + } + + } + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus addAdditionalInformationToResource(TitanVertex metadataVertex, String resourceUniqueId, List additionalInformation) { + + StorageOperationStatus result = null; + if (additionalInformation == null || true == additionalInformation.isEmpty()) { + result = super.addAdditionalInformation(NodeTypeEnum.Resource, resourceUniqueId, null, metadataVertex); + } else { + if (additionalInformation.size() == 1) { + result = super.addAdditionalInformation(NodeTypeEnum.Resource, resourceUniqueId, additionalInformation.get(0)); + } else { + result = StorageOperationStatus.BAD_REQUEST; + log.info("Cannot create resource with more than one additional information object. The number of received object is {}", additionalInformation.size()); + } + } + return result; + } + + private void generateUUID(Resource resource) { + String prevUUID = resource.getUUID(); + String version = resource.getVersion(); + if ((prevUUID == null && uuidNormativeNewVersion.matcher(version).matches()) || uuidNewVersion.matcher(version).matches()) { + UUID uuid = UUID.randomUUID(); + resource.setUUID(uuid.toString()); + MDC.put("serviceInstanceID", uuid.toString()); + } + } + + @Override + public Either overrideResource(Resource resource, Resource resourceSaved, boolean inTransaction) { + Either result = null; + try { + String resourceId = resourceSaved.getUniqueId(); + + // override interfaces to copy only resource's interfaces and not + // derived interfaces + Either, StorageOperationStatus> interfacesOfResourceOnly = interfaceLifecycleOperation.getAllInterfacesOfResource(resourceSaved.getUniqueId(), false, true); + if (interfacesOfResourceOnly.isRight()) { + log.error("failed to get interfaces of resource. resourceId {} status is {}", resourceId, interfacesOfResourceOnly.right().value()); + result = Either.right(interfacesOfResourceOnly.right().value()); + return result; + } + resource.setInterfaces(interfacesOfResourceOnly.left().value()); + resource.setArtifacts(resourceSaved.getArtifacts()); + resource.setDeploymentArtifacts(resourceSaved.getDeploymentArtifacts()); + resource.setGroups(resourceSaved.getGroups()); + resource.setInputs(null); + resource.setLastUpdateDate(null); + resource.setHighestVersion(true); + + // delete former resource + Either deleteResource = deleteResource(resourceId, true); + if (deleteResource.isRight()) { + log.error("failed to delete old resource with id {}. status = {}", resourceId, deleteResource.right().value()); + result = deleteResource; + return result; + } + + Either createResource = createResource(resource, true); + if (createResource.isRight()) { + log.error("failed to create new version of resource {} status = {}", resourceId, createResource.right().value()); + result = createResource; + return result; + } + Resource newResource = createResource.left().value(); + + Either, StorageOperationStatus> cloneGroupEither = cloneGroups(resource, newResource, null, inTransaction); + if (cloneGroupEither.isLeft()) { + newResource.setGroups(cloneGroupEither.left().value()); + } else if (cloneGroupEither.right().value() != StorageOperationStatus.OK) { + log.error("failed to clone group of resource {} status = {}", resourceId, cloneGroupEither.right().value()); + result = Either.right(cloneGroupEither.right().value()); + return result; + } + + result = Either.left(newResource); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private StorageOperationStatus associateCapabilitiesToResource(TitanVertex metadataVertex, String resourceIda, Map> capabilities) { + StorageOperationStatus addCapabilityToResource = null; + if (capabilities != null) { + for (Entry> entry : capabilities.entrySet()) { + + List capDefinition = entry.getValue(); + for (CapabilityDefinition item : capDefinition) { + addCapabilityToResource = capabilityOperation.addCapability(metadataVertex, resourceIda, item.getName(), item, true); + if (!addCapabilityToResource.equals(StorageOperationStatus.OK)) { + return addCapabilityToResource; + } + + } + } + + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus associateRequirementsToResource(TitanVertex metadataVertex, String resourceId, Map> requirements) { + + if (requirements != null) { + for (Entry> entry : requirements.entrySet()) { + + List reqDefinition = entry.getValue(); + for (RequirementDefinition item : reqDefinition) { + StorageOperationStatus addRequirementToResource = requirementOperation.addRequirementToResource(metadataVertex, item.getName(), item, resourceId, true); + + if (!addRequirementToResource.equals(StorageOperationStatus.OK)) { + return addRequirementToResource; + } + } + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus associateArtifactsToResource(TitanVertex metadataVertex, String resourceId, Map artifacts) { + + StorageOperationStatus status = StorageOperationStatus.OK; + if (artifacts != null) { + for (Entry entry : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + status = artifactOperation.addArifactToComponent(artifactDefinition, resourceId, NodeTypeEnum.Resource, false, metadataVertex); + + if (!status.equals(StorageOperationStatus.OK)) { + return status; + } + } + } + return status; + + } + + private StorageOperationStatus associateInterfacesToResource(ResourceMetadataData resourceData, Map interfaces, TitanVertex metadataVertex) { + + if (interfaces != null) { + for (Entry entry : interfaces.entrySet()) { + + InterfaceDefinition interfaceDefinition = entry.getValue(); + StorageOperationStatus status; + if (((ResourceMetadataDataDefinition) resourceData.getMetadataDataDefinition()).isAbstract()) { + status = interfaceLifecycleOperation.associateInterfaceToNode(resourceData, interfaceDefinition, metadataVertex); + } else { + status = interfaceLifecycleOperation.createInterfaceOnResource(interfaceDefinition, resourceData.getMetadataDataDefinition().getUniqueId(), interfaceDefinition.getType(), false, true, metadataVertex); + } + + if (!status.equals(StorageOperationStatus.OK)) { + return status; + } + } + } + return StorageOperationStatus.OK; + + } + + private Either sendError(TitanOperationStatus status, StorageOperationStatus statusIfNotFound) { + Either result; + if (status == TitanOperationStatus.NOT_FOUND) { + result = Either.right(statusIfNotFound); + return result; + } else { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + private TitanOperationStatus associatePropertiesToResource(TitanVertex metadatVertex, String resourceId, List properties) { + + Either, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + return status; + } + + Map convertedProperties = new HashMap<>(); + + if (properties != null) { + for (PropertyDefinition propertyDefinition : properties) { + convertedProperties.put(propertyDefinition.getName(), propertyDefinition); + } + TitanOperationStatus operationStatus = propertyOperation.addPropertiesToGraph(metadatVertex, convertedProperties, allDataTypes.left().value(), resourceId); + return operationStatus; + } + + return TitanOperationStatus.OK; + + } + + private TitanOperationStatus associateAttributesToResource(TitanVertex metadataVertex, List attributes, String resourceId) { + TitanOperationStatus operationStatus = TitanOperationStatus.OK; + + Either, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + return status; + } + + if (attributes != null) { + Map convertedAttributes = attributes.stream().collect(Collectors.toMap(e -> e.getName(), e -> e)); + operationStatus = attributeOperation.addAttributesToGraph(metadataVertex, convertedAttributes, resourceId, allDataTypes.left().value()); + } + return operationStatus; + } + + private TitanOperationStatus associateMetadataToResource(ResourceMetadataData resourceData, TitanVertex creatorVertex, TitanVertex updaterVertex, List derivedResources, TitanVertex metadataVertex) { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), resourceData.getMetadataDataDefinition().getState()); + + TitanOperationStatus result = titanGenericDao.createEdge(updaterVertex, metadataVertex, GraphEdgeLabels.STATE, props); + log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, resourceData.getUniqueId(), GraphEdgeLabels.STATE); + if (!result.equals(TitanOperationStatus.OK)) { + return result; + } + result = titanGenericDao.createEdge(updaterVertex, metadataVertex, GraphEdgeLabels.LAST_MODIFIER, null); + log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, resourceData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + if (!result.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate user {} to resource {}. Edge type is {}", updaterVertex, resourceData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + return result; + } + + result = titanGenericDao.createEdge(creatorVertex, metadataVertex, GraphEdgeLabels.CREATOR, null); + log.debug("After associating user {} to resource {}. Edge type is {} ", creatorVertex, resourceData.getUniqueId(), GraphEdgeLabels.CREATOR); + if (!result.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate user {} to resource {}. Edge type is {} ", creatorVertex, resourceData.getUniqueId(), GraphEdgeLabels.CREATOR); + return result; + } + // TODO Evg : need to change too.. + if (derivedResources != null) { + for (ResourceMetadataData derivedResource : derivedResources) { + log.debug("After associating resource " + resourceData.getUniqueId() + " to parent resource " + derivedResource.getUniqueId() + ". Edge type is " + GraphEdgeLabels.DERIVED_FROM); + Either createRelationResult = titanGenericDao.createRelation(resourceData, derivedResource, GraphEdgeLabels.DERIVED_FROM, null); + if (createRelationResult.isRight()) { + log.error("Failed to associate resource {} to derived ", resourceData.getUniqueId()); + return createRelationResult.right().value(); + } + } + } + + return TitanOperationStatus.OK; + } + + public Either, StorageOperationStatus> findDerivedResources(Resource resource) { + + List derivedResources = new ArrayList(); + List derivedFromResources = resource.getDerivedFrom(); + if (derivedFromResources != null && false == derivedFromResources.isEmpty()) { + + for (String parentResource : derivedFromResources) { + + Map propertiesToMatch = new HashMap(); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + // propertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), + // true); + propertiesToMatch.put(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), parentResource); + propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either, TitanOperationStatus> getParentResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + List resources = null; + if (getParentResources.isRight()) { + /* + * log.debug( "Cannot find parent resource by tosca resource name" + parentResource + " in the graph. Try to find by name"); Map propertiesWithResourceNameToMatch = new HashMap(); + * propertiesWithResourceNameToMatch.put( GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); propertiesWithResourceNameToMatch.put( GraphPropertiesDictionary.NAME.getProperty(), parentResource); + * propertiesWithResourceNameToMatch.put( GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty( ), true); + * + * getParentResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesWithResourceNameToMatch, ResourceData.class); if (getParentResources.isRight()) { log.error( + * "Cannot find parent resource by tosca resource name" + parentResource + " in the graph."); return Either.right(StorageOperationStatus. PARENT_RESOURCE_NOT_FOUND); }else{ resources = getParentResources.left().value(); + * + * } + */ + log.error("Cannot find parent resource by tosca resource name" + parentResource + " in the graph."); + return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND); + + } else { + resources = getParentResources.left().value(); + if (resources == null || resources.size() == 0) { + log.error("Cannot find parent resource by tosc name" + parentResource + " in the graph. resources size is empty"); + return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND); + } else { + if (resources.size() > 1) { + log.error("Multiple parent resources called " + parentResource + " found in the graph."); + return Either.right(StorageOperationStatus.MULTIPLE_PARENT_RESOURCE_FOUND); + } + ResourceMetadataData parentResourceData = resources.get(0); + derivedResources.add(parentResourceData); + } + + } + + } + } + return Either.left(derivedResources); + } + + private ResourceMetadataData getResourceMetaDataFromResource(Resource resource) { + ResourceMetadataData resourceData = new ResourceMetadataData((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()); + if (resource.getNormalizedName() == null || resource.getNormalizedName().isEmpty()) { + resourceData.getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(resource.getName())); + } + if (resource.getSystemName() == null || resource.getSystemName().isEmpty()) { + resourceData.getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(resource.getName())); + } + + LifecycleStateEnum lifecycleStateEnum = resource.getLifecycleState(); + if (lifecycleStateEnum == null) { + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + } + long currentDate = System.currentTimeMillis(); + if (resource.getCreationDate() == null) { + resourceData.getMetadataDataDefinition().setCreationDate(currentDate); + } + resourceData.getMetadataDataDefinition().setLastUpdateDate(currentDate); + + return resourceData; + } + + private ResourceMetadataData getResourceMetaDataForUpdate(Resource resource) { + // PA - please note: if you add here any fields, make sure they are + // validated (if needed) + // at ResourceBusinessLogic.validateResourceFieldsBeforeUpdate() and + // tested at ResourceBusinessLogicTest. + ResourceMetadataData resourceData = getResourceMetaDataFromResource(resource); + // resourceData.setLastUpdateDate(System.currentTimeMillis()); + // resourceData.setHighestVersion(resource.isHighestVersion()); + // resourceData.setNormalizedName(resource.getNormalizedName()); + // resourceData.setResourceType(resource.getResourceType().name()); + + return resourceData; + } + + public Either getResource(String uniqueId) { + return getResource(uniqueId, false); + } + + public Either getResource(String uniqueId, boolean inTransaction) { + ComponentParametersView componentParametersView = new ComponentParametersView(); + return getResource(uniqueId, componentParametersView, inTransaction); + } + + // public Either getResource(String + // uniqueId, boolean inTransaction) { + // + // Resource resource = null; + // try { + // + // NodeTypeEnum resourceNodeType = NodeTypeEnum.Resource; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + // + // Either + // componentByLabelAndId = getComponentByLabelAndId(uniqueId, + // resourceNodeType, ResourceMetadataData.class); + // if (componentByLabelAndId.isRight()) { + // return Either.right(componentByLabelAndId.right().value()); + // } + // ResourceMetadataData resourceData = componentByLabelAndId.left().value(); + // resource = convertResourceDataToResource(resourceData); + // + // TitanOperationStatus status = setResourceCreatorFromGraph(resource, + // uniqueId); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceLastModifierFromGraph(resource, uniqueId); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourcePropertiesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceAttributesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceDerivedFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setComponentCategoriesFromGraph(resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setComponentInstancesFromGraph(uniqueId, resource, + // resourceNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // StorageOperationStatus setRequirementsStatus = + // setResourceRequirementsFromGraph(uniqueId, resource, true); + // if (setRequirementsStatus != StorageOperationStatus.OK) { + // log.error("Failed to set requirement of resource " + uniqueId + ". status + // is " + setRequirementsStatus); + // return Either.right(setRequirementsStatus); + // } + // + // StorageOperationStatus storageStatus = + // setResourceCapabilitiesFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // storageStatus = setArtifactFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // status = setComponentInstancesAttributesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // storageStatus = setResourceInterfacesFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // storageStatus = setResourceAdditionalInformationFromGraph(uniqueId, + // resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // status = setAllVersions(resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setGroupsFromGraph(uniqueId, resource, NodeTypeEnum.Resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // } finally { + // if (false == inTransaction) { + // titanGenericDao.commit(); + // } + // } + // + // return Either.left(resource); + // } + + private TitanOperationStatus setComponentInstancesAttributesFromGraph(String uniqueId, Resource component) { + Map> resourceInstancesAttributes = new HashMap<>(); + TitanOperationStatus status = TitanOperationStatus.OK; + List componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + for (ComponentInstance resourceInstance : componentInstances) { + Either, TitanOperationStatus> eitherRIAttributes = attributeOperation.getAllAttributesOfResourceInstance(resourceInstance); + if (eitherRIAttributes.isRight()) { + status = eitherRIAttributes.right().value(); + break; + } else { + resourceInstancesAttributes.put(resourceInstance.getUniqueId(), eitherRIAttributes.left().value()); + } + } + + component.setComponentInstancesAttributes(resourceInstancesAttributes); + } + + return status; + + } + + // public Either getResource_tx(String + // uniqueId, boolean inTransaction) { + // + // Resource resource = null; + // try { + // + // NodeTypeEnum resourceNodeType = NodeTypeEnum.Resource; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + // + // Either + // componentByLabelAndId = getComponentByLabelAndId_tx(uniqueId, + // resourceNodeType, ResourceMetadataData.class); + // if (componentByLabelAndId.isRight()) { + // return Either.right(componentByLabelAndId.right().value()); + // } + // ResourceMetadataData resourceData = componentByLabelAndId.left().value(); + // resource = convertResourceDataToResource(resourceData); + // + // TitanOperationStatus status = setResourceCreatorFromGraph(resource, + // uniqueId); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceLastModifierFromGraph(resource, uniqueId); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourcePropertiesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceDerivedFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setComponentCategoriesFromGraph(resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setComponentInstancesFromGraph(uniqueId, resource, + // resourceNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // StorageOperationStatus setRequirementsStatus = + // setResourceRequirementsFromGraph(uniqueId, resource, true); + // if (setRequirementsStatus != StorageOperationStatus.OK) { + // log.error("Failed to set requirement of resource " + uniqueId + ". status + // is " + setRequirementsStatus); + // return Either.right(setRequirementsStatus); + // } + // + // StorageOperationStatus storageStatus = + // setResourceCapabilitiesFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // storageStatus = setArtifactFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // storageStatus = setResourceInterfacesFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // storageStatus = setResourceAdditionalInformationFromGraph(uniqueId, + // resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // status = setAllVersions(resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // } finally { + // if (false == inTransaction) { + // titanGenericDao.commit(); + // } + // } + // + // return Either.left(resource); + // } + + private StorageOperationStatus setResourceAdditionalInformationFromGraph(String uniqueId, Resource resource) { + + List additionalInformation = new ArrayList<>(); + + Either either = additionalInformationOperation.getAllAdditionalInformationParameters(NodeTypeEnum.Resource, uniqueId, true, true); + + if (either.isRight()) { + StorageOperationStatus status = either.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + return StorageOperationStatus.OK; + } + return status; + } + + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + additionalInformation.add(additionalInformationDefinition); + + resource.setAdditionalInformation(additionalInformation); + + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus setResourceInterfacesFromGraph(String uniqueId, Resource resource) { + + Either, StorageOperationStatus> statusRes = interfaceLifecycleOperation.getAllInterfacesOfResource(uniqueId, true, true); + if (statusRes.isRight()) { + return statusRes.right().value(); + } + Map value = statusRes.left().value(); + + resource.setInterfaces(value); + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus setResourceCapabilitiesFromGraph(String uniqueId, Resource resource) { + StorageOperationStatus retStatus; + Either, StorageOperationStatus> result = capabilityOperation.getAllCapabilitiesOfResource(uniqueId, true, true); + if (result.isRight()) { + StorageOperationStatus status = result.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + retStatus = status; + } else { + retStatus = StorageOperationStatus.OK; + } + } else { + Map capabilities = result.left().value(); + if (capabilities == null || capabilities.isEmpty()) { + Either>, TitanOperationStatus> eitherCapabilities = super.getCapabilities(resource, NodeTypeEnum.Resource, true); + if (eitherCapabilities.isLeft()) { + retStatus = StorageOperationStatus.OK; + Map> calculatedCapabilities = eitherCapabilities.left().value(); + resource.setCapabilities(calculatedCapabilities); + } else { + retStatus = StorageOperationStatus.GENERAL_ERROR; + } + + } else { + retStatus = StorageOperationStatus.OK; + resource.setCapabilities(capabilityOperation.convertCapabilityMap(capabilities, null, null)); + } + + } + return retStatus; + + } + + public Either>, TitanOperationStatus> getCapabilities(org.openecomp.sdc.be.model.Component component, NodeTypeEnum componentTypeEnum, boolean inTransaction) { + + try { + Either, StorageOperationStatus> result = capabilityOperation.getAllCapabilitiesOfResource(component.getUniqueId(), true, true); + if (result.isRight() || result.left().value().isEmpty()) { + final Either>, TitanOperationStatus> eitherCapabilities = super.getCapabilities(component, componentTypeEnum, inTransaction); + return eitherCapabilities; + } else { + return Either.left(capabilityOperation.convertCapabilityMap(result.left().value(), null, null)); + } + } finally { + if (inTransaction == false) { + titanGenericDao.commit(); + } + } + } + + public Either>, TitanOperationStatus> getRequirements(org.openecomp.sdc.be.model.Component component, NodeTypeEnum componentTypeEnum, boolean inTransaction) { + try { + Either, StorageOperationStatus> result = requirementOperation.getAllResourceRequirements(component.getUniqueId(), true); + if (result.isRight() || result.left().value().isEmpty()) { + final Either>, TitanOperationStatus> eitherCapabilities = super.getRequirements(component, componentTypeEnum, true); + return eitherCapabilities; + } else { + return Either.left(requirementOperation.convertRequirementMap(result.left().value(), null, null)); + } + } finally { + if (inTransaction == false) { + titanGenericDao.commit(); + } + } + + } + + private StorageOperationStatus setResourceRequirementsFromGraph(String uniqueId, Resource resource, boolean inTransaction) { + StorageOperationStatus retStatus; + Either, StorageOperationStatus> result = requirementOperation.getAllResourceRequirements(uniqueId, inTransaction); + ; + if (result.isRight()) { + StorageOperationStatus status = result.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + retStatus = status; + } else { + retStatus = StorageOperationStatus.OK; + } + } else { + Map requirements = result.left().value(); + if (requirements == null || requirements.isEmpty()) { + Either>, TitanOperationStatus> eitherCapabilities = super.getRequirements(resource, NodeTypeEnum.Resource, true); + if (eitherCapabilities.isLeft()) { + retStatus = StorageOperationStatus.OK; + Map> calculatedCapabilities = eitherCapabilities.left().value(); + resource.setRequirements(calculatedCapabilities); + } else { + retStatus = StorageOperationStatus.GENERAL_ERROR; + } + + } else { + retStatus = StorageOperationStatus.OK; + resource.setRequirements(requirementOperation.convertRequirementMap(requirements, null, null)); + } + + } + return retStatus; + } + + private TitanOperationStatus setResourcePropertiesFromGraph(String uniqueId, Resource resource) { + + List properties = new ArrayList<>(); + TitanOperationStatus status = propertyOperation.findAllResourcePropertiesRecursively(uniqueId, properties); + if (status == TitanOperationStatus.OK) { + resource.setProperties(properties); + } + + return status; + + } + + private TitanOperationStatus setResourceAttributesFromGraph(String uniqueId, Resource resource) { + + List attributes = new ArrayList<>(); + TitanOperationStatus status = attributeOperation.findAllResourceAttributesRecursively(uniqueId, attributes); + if (status == TitanOperationStatus.OK) { + resource.setAttributes(attributes); + } + + return status; + + } + + private TitanOperationStatus setResourceDerivedFromGraph(String uniqueId, Resource resource) { + List derivedFromList = new ArrayList(); + + TitanOperationStatus listFromGraphStatus = fillResourceDerivedListFromGraph(uniqueId, derivedFromList); + if (!TitanOperationStatus.OK.equals(listFromGraphStatus)) { + return listFromGraphStatus; + } + + if (false == derivedFromList.isEmpty()) { + if (derivedFromList.size() > 1) { + List lastDerivedFrom = new ArrayList(); + lastDerivedFrom.add(derivedFromList.get(1)); + resource.setDerivedFrom(lastDerivedFrom); + resource.setDerivedList(derivedFromList); + } else { + resource.setDerivedFrom(null); + resource.setDerivedList(derivedFromList); + } + + } + + return TitanOperationStatus.OK; + } + + public TitanOperationStatus fillResourceDerivedListFromGraph(String uniqueId, List derivedFromList) { + // Either>, + // TitanOperationStatus> childrenNodes = + // titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), + // uniqueId, GraphEdgeLabels.DERIVED_FROM, + // NodeTypeEnum.Resource, ResourceMetadataData.class); + // + // if (childrenNodes.isRight() && (childrenNodes.right().value() != + // TitanOperationStatus.NOT_FOUND)) { + // return childrenNodes.right().value(); + // } else if (childrenNodes.isLeft()) { + // + // List> pairList = + // childrenNodes.left().value(); + // for (ImmutablePair pair : pairList) + // { + // derivedFromList.add(pair.left.getMetadataDataDefinition().getName()); + // return + // fillResourceDerivedListFromGraph(pair.left.getMetadataDataDefinition().getUniqueId(), + // derivedFromList); + // } + // } + List derivedData = new ArrayList(); + TitanOperationStatus findResourcesPathRecursively = findResourcesPathRecursively(uniqueId, derivedData); + if (!findResourcesPathRecursively.equals(TitanOperationStatus.OK)) { + return findResourcesPathRecursively; + } + derivedData.forEach(resourceData -> derivedFromList.add(((ResourceMetadataDataDefinition) resourceData.getMetadataDataDefinition()).getToscaResourceName())); + return TitanOperationStatus.OK; + } + + private TitanOperationStatus setResourceLastModifierFromGraph(Resource resource, String resourceId) { + + Either, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.LAST_MODIFIER, NodeTypeEnum.User, + UserData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + ImmutablePair value = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + UserData userData = value.getKey(); + + if (log.isDebugEnabled()) { + log.debug("Build resource : set last modifier userId to {}", userData.getUserId()); + } + + String fullName = buildFullName(userData); + if (log.isDebugEnabled()) + log.debug("Build resource : set last modifier full name to {}", fullName); + resource.setLastUpdaterUserId(userData.getUserId()); + resource.setLastUpdaterFullName(fullName); + + return TitanOperationStatus.OK; + } + + private TitanOperationStatus setResourceCreatorFromGraph(Resource resource, String resourceId) { + + Either, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.CREATOR, NodeTypeEnum.User, UserData.class); + if (parentNode.isRight()) { + log.debug("Failed to find the creator of resource {}", resourceId); + return parentNode.right().value(); + } + + ImmutablePair value = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + UserData userData = value.getKey(); + if (log.isDebugEnabled()) { + log.debug("Build resource : set creator userId to {}", userData.getUserId()); + } + String fullName = buildFullName(userData); + if (log.isDebugEnabled()) + log.debug("Build resource : set creator full name to {}", fullName); + resource.setCreatorUserId(userData.getUserId()); + resource.setCreatorFullName(fullName); + + return TitanOperationStatus.OK; + } + + @Override + TitanOperationStatus setComponentCategoriesFromGraph(Component resource) { + String uniqueId = resource.getUniqueId(); + Either>, TitanOperationStatus> parentNode = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, GraphEdgeLabels.CATEGORY, + NodeTypeEnum.ResourceSubcategory, SubCategoryData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + List> listValue = parentNode.left().value(); + log.debug("Result after looking for subcategory nodes pointed by resource {}. status is {}", uniqueId, listValue); + if (listValue.size() > 1) { + log.error("Multiple edges foud between resource {} to subcategory nodes.", uniqueId); + } + ImmutablePair value = listValue.get(0); + log.debug("Found parent node {}", value); + + SubCategoryData subcategoryData = value.getKey(); + + Either, TitanOperationStatus> categoryNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceSubcategory), (String) subcategoryData.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceNewCategory, CategoryData.class); + if (categoryNode.isRight()) { + return categoryNode.right().value(); + } + + CategoryData categoryData = categoryNode.left().value().left; + CategoryDefinition catDef = new CategoryDefinition(categoryData.getCategoryDataDefinition()); + SubCategoryDefinition subcatDef = new SubCategoryDefinition(subcategoryData.getSubCategoryDataDefinition()); + + resource.addCategory(catDef, subcatDef); + return TitanOperationStatus.OK; + } + + public String buildFullName(UserData userData) { + + String fullName = userData.getFirstName(); + if (fullName == null) { + fullName = ""; + } else { + fullName = fullName + " "; + } + String lastName = userData.getLastName(); + if (lastName != null) { + fullName += lastName; + } + return fullName; + } + + private Resource convertResourceDataToResource(ResourceMetadataData resourceData) { + + ResourceMetadataDefinition resourceMetadataDataDefinition = new ResourceMetadataDefinition((ResourceMetadataDataDefinition) resourceData.getMetadataDataDefinition()); + + Resource resource = new Resource(resourceMetadataDataDefinition); + + return resource; + } + + @Override + public Either deleteResource(String resourceId) { + return deleteResource(resourceId, false); + } + + @Override + public Either updateResource(Resource resource) { + + return updateResource(resource, false); + + } + + @Override + public Either getNumberOfResourcesByName(String resourceName) { + + Map propertiesToMatch = new HashMap(); + propertiesToMatch.put(GraphPropertiesDictionary.NAME.getProperty(), resourceName); + + Either, TitanOperationStatus> getParentResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + log.debug("result after searching for resources called " + resourceName + " is " + getParentResources); + if (getParentResources.isRight()) { + TitanOperationStatus titanStatus = getParentResources.right().value(); + if (titanStatus == TitanOperationStatus.NOT_FOUND) { + log.debug("Number of returned resources is 0."); + return Either.left(0); + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus)); + } else { + List value = getParentResources.left().value(); + int numberOFResources = (value == null ? 0 : value.size()); + log.debug("The number of resources returned after searching for resource called " + resourceName + " is " + numberOFResources); + return Either.left(numberOFResources); + } + } + + public PropertyOperation getPropertyOperation() { + return propertyOperation; + } + + public void setPropertyOperation(PropertyOperation propertyOperation) { + this.propertyOperation = propertyOperation; + } + + public RequirementOperation getRequirementOperation() { + return requirementOperation; + } + + public void setRequirementOperation(RequirementOperation requirementOperation) { + this.requirementOperation = requirementOperation; + } + + public CapabilityOperation getCapabilityOperation() { + return capabilityOperation; + } + + public void setCapabilityOperation(CapabilityOperation capabilityOperation) { + this.capabilityOperation = capabilityOperation; + } + + public IArtifactOperation getArtifactOperation() { + return artifactOperation; + } + + public void setArtifactOperation(IArtifactOperation artifactOperation) { + this.artifactOperation = artifactOperation; + } + + public InterfaceLifecycleOperation getInterfaceLifecycleOperation() { + return interfaceLifecycleOperation; + } + + public void setInterfaceLifecycleOperation(InterfaceLifecycleOperation interfaceLifecycleOperation) { + this.interfaceLifecycleOperation = interfaceLifecycleOperation; + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public IElementOperation getElementOperation() { + return elementOperation; + } + + public void setElementOperation(IElementOperation elementOperation) { + this.elementOperation = elementOperation; + } + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either, StorageOperationStatus> getAllCertifiedResources(boolean isAbstract) { + + return getAllCertifiedResources(isAbstract, null); + + } + + @Override + /** + * Deletes the resource node, property nodes and relation to artifacts. MUST handle deletion of artifact from artifacts repository outside this method (in catalog-be) + */ + public Either deleteResource(String resourceId, boolean inTransaction) { + + Either result = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + + TitanGraph titanGraph = graphResult.left().value(); + Iterable vertecies = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId).vertices(); + Either resourceEither = getResource(resourceId, true); + Resource resource = resourceEither.left().value(); + if (vertecies != null && resourceEither.isLeft()) { + Iterator iterator = vertecies.iterator(); + if (iterator != null && iterator.hasNext()) { + Vertex rootVertex = iterator.next(); + TitanOperationStatus deleteChildrenNodes = graphDeleteUtil.deleteChildrenNodes(rootVertex, GraphEdgeLabels.PROPERTY); + log.debug("After deleting properties nodes in the graph. status is " + deleteChildrenNodes); + if (deleteChildrenNodes != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteChildrenNodes)); + return result; + } + StorageOperationStatus removeInterfacesFromResource = removeInterfacesFromResource(resource); + log.debug("After deleting interfaces nodes in the graph. status is " + removeInterfacesFromResource); + if (!removeInterfacesFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeInterfacesFromResource); + return result; + } + StorageOperationStatus removeArtifactsFromResource = removeArtifactsFromResource(resource); + log.debug("After deleting artifacts nodes in the graph. status is " + removeArtifactsFromResource); + if (!removeArtifactsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeArtifactsFromResource); + return result; + } + StorageOperationStatus removeCapabilitiesFromResource = removeCapabilitiesFromResource(resource); + log.debug("After deleting capabilities nodes in the graph. status is " + removeCapabilitiesFromResource); + if (!removeCapabilitiesFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeCapabilitiesFromResource); + return result; + } + + StorageOperationStatus removeRequirementsFromResource = removeRequirementsFromResource(resource); + log.debug("After deleting requirements nodes in the graph. status is " + removeRequirementsFromResource); + if (!removeRequirementsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeRequirementsFromResource); + return result; + } + + StorageOperationStatus removeRIsFromResource = removeResourceInstanceFromResource(resource); + log.debug("After deleting resource instance nodes in the graph. status is " + removeRIsFromResource); + if (!removeRIsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeRIsFromResource); + return result; + } + + StorageOperationStatus removeAttributesFromResource = removeAttributesFromResource(resource); + log.debug("After deleting requirements nodes in the graph. status is " + removeRequirementsFromResource); + if (removeAttributesFromResource != StorageOperationStatus.OK) { + result = Either.right(removeAttributesFromResource); + return result; + } + + StorageOperationStatus removeInputsFromResource = removeInputsFromComponent(NodeTypeEnum.Resource, resource); + log.debug("After deleting requirements nodes in the graph. status is " + removeInputsFromResource); + if (removeInputsFromResource != StorageOperationStatus.OK) { + result = Either.right(removeInputsFromResource); + return result; + } + + StorageOperationStatus removeAdditionalInformationFromResource = super.deleteAdditionalInformation(NodeTypeEnum.Resource, resource.getUniqueId()); + log.debug("After deleting additional information node in the graph. status is " + removeAdditionalInformationFromResource); + if (!removeAdditionalInformationFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeAdditionalInformationFromResource); + return result; + } + + StorageOperationStatus removeGroupsFromResource = super.deleteGroups(NodeTypeEnum.Resource, resource.getUniqueId()); + log.debug("After deleting group nodes in the graph. status is " + removeGroupsFromResource); + if (!removeGroupsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeGroupsFromResource); + return result; + } + + rootVertex.remove(); + + } else { + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + } else { + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + + result = Either.left(resource); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("deleteResource operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("deleteResource operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private StorageOperationStatus removeAttributesFromResource(Resource resource) { + Either, StorageOperationStatus> deleteAllAttributeAssociatedToNode = attributeOperation.deleteAllAttributeAssociatedToNode(NodeTypeEnum.Resource, resource.getUniqueId()); + return deleteAllAttributeAssociatedToNode.isRight() ? deleteAllAttributeAssociatedToNode.right().value() : StorageOperationStatus.OK; + } + + private StorageOperationStatus removeArtifactsFromResource(Resource resource) { + + String resourceId = resource.getUniqueId(); + Map allArtifacts = new HashMap(); + if (resource.getArtifacts() != null) { + allArtifacts.putAll(resource.getArtifacts()); + } + if (resource.getDeploymentArtifacts() != null) { + allArtifacts.putAll(resource.getDeploymentArtifacts()); + } + if (allArtifacts != null) { + for (Entry entry : allArtifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + Either removeArifactFromResource = artifactOperation.removeArifactFromResource(resourceId, artifactDefinition.getUniqueId(), NodeTypeEnum.Resource, true, true); + if (removeArifactFromResource.isRight()) { + return removeArifactFromResource.right().value(); + } + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus removeInterfacesFromResource(Resource resource) { + + String resourceId = resource.getUniqueId(); + // delete only interfaces of this resource (not interfaces derived) + Either, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation.getAllInterfacesOfResource(resourceId, false, true); + if (allInterfacesOfResource.isRight()) { + log.error("failed to get interfaces for resource {}. status is {}", resourceId, allInterfacesOfResource.right().value()); + return allInterfacesOfResource.right().value(); + } + Map interfaces = allInterfacesOfResource.left().value(); + if (interfaces != null) { + for (Entry entry : interfaces.entrySet()) { + Boolean isAbstract = resource.isAbstract(); + + InterfaceDefinition interfaceDefinition = entry.getValue(); + // esofer - in case the resource is abstract, we deleting only + // the edge to the interface. + if (isAbstract != null && true == isAbstract.booleanValue()) { + log.debug("Going to dissociate resource {} from interface {}", resourceId, interfaceDefinition.getUniqueId()); + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.Resource, resourceId); + Either dissociateInterfaceFromNode = interfaceLifecycleOperation.dissociateInterfaceFromNode(uniqueIdData, interfaceDefinition); + if (dissociateInterfaceFromNode.isRight()) { + log.error("failed to dissociate resource {} from interface {}. status is {}", resourceId, interfaceDefinition.getUniqueId(), dissociateInterfaceFromNode.right().value()); + return dissociateInterfaceFromNode.right().value(); + } + } else { + Either deleteInterfaceOfResourceOnGraph = interfaceLifecycleOperation.deleteInterfaceOfResourceOnGraph(resourceId, interfaceDefinition, true); + if (deleteInterfaceOfResourceOnGraph.isRight()) { + return deleteInterfaceOfResourceOnGraph.right().value(); + } + } + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus removeCapabilitiesFromResource(Resource resource) { + + String resourceId = resource.getUniqueId(); + + Either, StorageOperationStatus> deleteAllRes = capabilityOperation.deleteAllCapabilities(resourceId, true); + if (deleteAllRes.isRight()) { + StorageOperationStatus status = deleteAllRes.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + return StorageOperationStatus.OK; + } + return status; + } + + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus removeRequirementsFromResource(Resource resource) { + + String resourceId = resource.getUniqueId(); + + Either, StorageOperationStatus> deleteAllRes = requirementOperation.deleteAllRequirements(resourceId, true); + + if (deleteAllRes.isRight()) { + StorageOperationStatus status = deleteAllRes.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + return StorageOperationStatus.OK; + } + return status; + } + + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus removeResourceInstanceFromResource(Resource resource) { + String resourceId = resource.getUniqueId(); + + Either, StorageOperationStatus> deleteAllResourceInstancesRes = componentInstanceOperation.deleteAllComponentInstances(resourceId, NodeTypeEnum.Resource, true); + if (deleteAllResourceInstancesRes.isRight()) { + StorageOperationStatus status = deleteAllResourceInstancesRes.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + return StorageOperationStatus.OK; + } + return status; + } + return StorageOperationStatus.OK; + } + + @Override + public Either updateResource(Resource resource, boolean inTransaction) { + return (Either) updateComponent(resource, inTransaction, titanGenericDao, resource.getClass(), NodeTypeEnum.Resource); + + } + + @Override + protected StorageOperationStatus updateDerived(Component component, Component currentComponent, ComponentMetadataData updatedResourceData, Class clazz) { + Resource resource = (Resource) component; + Resource currentResource = (Resource) currentComponent; + if (resource.getDerivedFrom() != null) {// meaning derived from changed + + Either, StorageOperationStatus> findDerivedResourcesOld = findDerivedResources(currentResource); + if (findDerivedResourcesOld.isRight()) { + log.debug("Couldn't find derived resource {} for current resource in the graph", currentResource.getDerivedFrom().get(0)); + return findDerivedResourcesOld.right().value(); + } + + List oldDerived = findDerivedResourcesOld.left().value(); + if (oldDerived.isEmpty()) { + log.debug("Derived from list fetched from DB for current resource is empty"); + return StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND; + } + + Either, StorageOperationStatus> findDerivedResourcesNew = findDerivedResources((Resource) resource); + if (findDerivedResourcesNew.isRight()) { + log.debug("Couldn't find derived resource {} for update resource in the graph", resource.getDerivedFrom().get(0)); + return findDerivedResourcesNew.right().value(); + } + + List newDerived = findDerivedResourcesNew.left().value(); + if (newDerived.isEmpty()) { + log.debug("Derived from list fetched from DB for updated resource is empty"); + return StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND; + } + + Either reassociateDerivedFrom = reassociateDerivedFrom((ResourceMetadataData) updatedResourceData, oldDerived, newDerived); + if (reassociateDerivedFrom.isRight()) { + log.debug("Couldn't change derived from for the resoure"); + return DaoStatusConverter.convertTitanStatusToStorageStatus(reassociateDerivedFrom.right().value()); + } + } + return StorageOperationStatus.OK; + } + + private Either reassociateDerivedFrom(ResourceMetadataData resourceData, List oldDerived, List newDerived) { + ResourceMetadataData oldDerivedNode = oldDerived.get(0); + log.debug("Dissociating resource {} from old parent resource {}", resourceData.getUniqueId(), oldDerivedNode.getUniqueId()); + Either deleteRelation = titanGenericDao.deleteRelation(resourceData, oldDerivedNode, GraphEdgeLabels.DERIVED_FROM); + if (deleteRelation.isRight()) { + log.debug("Failed to dissociate resource {} from old parent resource {}", resourceData.getUniqueId(), oldDerivedNode.getUniqueId()); + return Either.right(deleteRelation.right().value()); + } + ResourceMetadataData newDerivedNode = newDerived.get(0); + log.debug("Associating resource {} with new parent resource {}", resourceData.getUniqueId(), newDerivedNode.getUniqueId()); + Either addRelation = titanGenericDao.createRelation(resourceData, newDerivedNode, GraphEdgeLabels.DERIVED_FROM, null); + if (addRelation.isRight()) { + log.debug("Failed to associate resource {} with new parent resource {}", resourceData.getUniqueId(), newDerivedNode.getUniqueId()); + return Either.right(addRelation.right().value()); + } + + return Either.left(true); + } + + private StorageOperationStatus moveCategoryEdge(Resource resource, ResourceMetadataData resourceData, CategoryDefinition newCategory) { + + StorageOperationStatus result = StorageOperationStatus.OK; + + GraphRelation categoryRelation = new GraphRelation(); + categoryRelation.setType(GraphEdgeLabels.CATEGORY.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(NodeTypeEnum.Resource, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resource.getUniqueId()); + categoryRelation.setFrom(relationEndPoint); + Either deleteOutgoingRelation = titanGenericDao.deleteOutgoingRelation(categoryRelation); + if (deleteOutgoingRelation.isRight()) { + log.error("Failed to delete category from resource " + resourceData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.CATEGORY); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteOutgoingRelation.right().value()); + return result; + } + + log.debug("After removing edge from graph " + deleteOutgoingRelation); + + return assosiateMetadataToCategory(resource, resourceData); + } + + private StorageOperationStatus moveLastModifierEdge(Resource resource, ResourceMetadataData resourceData, UserData modifierUserData) { + + StorageOperationStatus result = StorageOperationStatus.OK; + + GraphRelation lastModifierRelation = new GraphRelation(); + lastModifierRelation.setType(GraphEdgeLabels.LAST_MODIFIER.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(NodeTypeEnum.Resource, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resource.getUniqueId()); + lastModifierRelation.setTo(relationEndPoint); + Either deleteIncomingRelation = titanGenericDao.deleteIncomingRelation(lastModifierRelation); + if (deleteIncomingRelation.isRight()) { + log.error("Failed to delete user from resource " + resourceData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.LAST_MODIFIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteIncomingRelation.right().value()); + return result; + } + + Either createRelation = titanGenericDao.createRelation(modifierUserData, resourceData, GraphEdgeLabels.LAST_MODIFIER, null); + log.debug("After associating user " + modifierUserData + " to resource " + resourceData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.LAST_MODIFIER); + if (createRelation.isRight()) { + log.error("Failed to associate user " + modifierUserData + " to resource " + resourceData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.LAST_MODIFIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation.right().value()); + return result; + } + + return result; + } + + private Either findResource(String resourceId) { + + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource); + Either findResource = titanGenericDao.getNode(key, resourceId, ResourceMetadataData.class); + + return findResource; + } + + private StorageOperationStatus setArtifactFromGraph(String uniqueId, Resource resource) { + StorageOperationStatus result = StorageOperationStatus.OK; + Either, StorageOperationStatus> artifacts = artifactOperation.getArtifacts(uniqueId, NodeTypeEnum.Resource, true); + if (artifacts.isRight()) { + result = artifacts.right().value(); + } else { + createSpecificArtifactList(resource, artifacts.left().value()); + } + return result; + } + + @Override + public Either getComponent(String id, Class clazz) { + + Either component = getResource(id); + if (component.isRight()) { + return Either.right(component.right().value()); + } + return Either.left(clazz.cast(component.left().value())); + } + + @Override + public Either validateResourceNameExists(String resourceName, ResourceTypeEnum resourceType) { + if (resourceType != null) { + Map properties = new HashMap(); + properties.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + if (resourceType.equals(ResourceTypeEnum.VF)) { + return validateResourceNameUniqueness(resourceName, properties, null, titanGenericDao); + } else { + return validateResourceNameUniqueness(resourceName, null, properties, titanGenericDao); + } + + } else { + return validateResourceNameUniqueness(resourceName, null, null, titanGenericDao); + } + + } + + public Either validateToscaResourceNameExists(String templateName) { + return validateToscaResourceNameUniqueness(templateName, titanGenericDao); + } + + public Either, StorageOperationStatus> getAdditionalArtifacts(String resourceId, boolean recursively, boolean inTransaction) { + List artifacts = new ArrayList<>(); + + Either, StorageOperationStatus> interfacesOfResource = interfaceLifecycleOperation.getAllInterfacesOfResource(resourceId, false, true); + if (interfacesOfResource.isRight()) { + log.error("failed to get all resource interfaces. resource id={}. status ={}", resourceId, interfacesOfResource.right().value()); + return Either.right(interfacesOfResource.right().value()); + } + + Map interfaces = interfacesOfResource.left().value(); + if (interfaces != null && !interfaces.isEmpty()) { + for (Entry entry : interfaces.entrySet()) { + + InterfaceDefinition interfaceDefinition = entry.getValue(); + Map operations = interfaceDefinition.getOperations(); + if (operations != null && !operations.isEmpty()) { + for (Entry opEntry : operations.entrySet()) { + + Operation operation = opEntry.getValue(); + ArtifactDefinition artifactDefinition = operation.getImplementation(); + if (artifactDefinition != null) { + artifacts.add(artifactDefinition); + } + } + } + } + } + return Either.left(artifacts); + } + + @SuppressWarnings("unchecked") + public Either, StorageOperationStatus> getFollowed(String userId, Set lifecycleStates, Set lastStateStates, boolean inTransaction) { + return (Either, StorageOperationStatus>) (Either) getFollowedComponent(userId, lifecycleStates, lastStateStates, inTransaction, titanGenericDao, NodeTypeEnum.Resource); + } + + @SuppressWarnings("unchecked") + @Override + public Either getComponent(String id, boolean inTransaction) { + return (Either) getResource(id, inTransaction); + } + + private Optional> validateCategoryHierarcy(List> childNodes, String subCategoryName) { + Predicate> matchName = p -> p.getLeft().getSubCategoryDataDefinition().getName().equals(subCategoryName); + return childNodes.stream().filter(matchName).findAny(); + } + + private Either>, StorageOperationStatus> getAllSubCategories(String categoryName) { + Either categoryResult = elementOperation.getNewCategoryData(categoryName, NodeTypeEnum.ResourceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + return Either.right(categoryResult.right().value()); + } + CategoryData categoryData = categoryResult.left().value(); + + Either>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), (String) categoryData.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceSubcategory, SubCategoryData.class); + if (childrenNodes.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenNodes.right().value())); + } + return Either.left(childrenNodes.left().value()); + } + + @Override + public Either, StorageOperationStatus> getFilteredComponents(Map filters, boolean inTransaction) { + + String subCategoryName = filters.get(FilterKeyEnum.SUB_CATEGORY); + String categoryName = filters.get(FilterKeyEnum.CATEGORY); + Either>, StorageOperationStatus> subcategories = null; + Optional> subCategoryData = null; + + if (categoryName != null) { + subcategories = getAllSubCategories(categoryName); + if (subcategories.isRight()) { + filters.remove(FilterKeyEnum.SUB_CATEGORY); + return Either.right(subcategories.right().value()); + } + } + if (subCategoryName != null) { // primary filter + if (categoryName != null) { + subCategoryData = validateCategoryHierarcy(subcategories.left().value(), subCategoryName); + if (!subCategoryData.isPresent()) { + return Either.right(StorageOperationStatus.MATCH_NOT_FOUND); + } + return fetchByCategoryOrSubCategoryUid((String) subCategoryData.get().getLeft().getUniqueId(), NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, inTransaction, + ResourceMetadataData.class); + } + + return fetchByCategoryOrSubCategoryName(subCategoryName, NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, inTransaction, ResourceMetadataData.class); + } + return fetchByMainCategory(subcategories.left().value(), inTransaction); + } + + private Either, StorageOperationStatus> fetchByMainCategory(List> subcategories, boolean inTransaction) { + List components = new ArrayList<>(); + + for (ImmutablePair subCategory : subcategories) { + Either, StorageOperationStatus> fetched = fetchByCategoryOrSubCategoryUid((String) subCategory.getLeft().getUniqueId(), NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, + inTransaction, ResourceMetadataData.class); + if (fetched.isRight()) { + // return fetched; + continue; + } + components.addAll(fetched.left().value()); + } + return Either.left(components); + } + + @Override + public Either getLightComponent(String id, boolean inTransaction) { + return getLightComponent(id, NodeTypeEnum.Resource, inTransaction); + } + + // will be implement later + @Override + protected ComponentMetadataData getMetaDataFromComponent(Component component) { + return getResourceMetaDataFromResource((Resource) component); + } + + @Override + public Either, StorageOperationStatus> getCatalogData(Map propertiesToMatch, boolean inTransaction) { + return getComponentCatalogData(NodeTypeEnum.Resource, propertiesToMatch, Resource.class, ResourceMetadataData.class, inTransaction); + } + + protected TitanOperationStatus findResourcesPathRecursively(String resourceId, List resourcesPathList) { + + Either nodeRes = this.titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, ResourceMetadataData.class); + + if (nodeRes.isRight()) { + TitanOperationStatus status = nodeRes.right().value(); + log.error("Failed to fetch resource {} . status is {}", resourceId, status); + return status; + } + + ResourceMetadataData resourceData = nodeRes.left().value(); + resourcesPathList.add(resourceData); + Either, TitanOperationStatus> parentResourceRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.Resource, ResourceMetadataData.class); + + while (parentResourceRes.isLeft()) { + + ImmutablePair value = parentResourceRes.left().value(); + ResourceMetadataData parentResourceData = value.getKey(); + + resourcesPathList.add(parentResourceData); + + parentResourceRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), parentResourceData.getMetadataDataDefinition().getUniqueId(), GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, + ResourceMetadataData.class); + } + + TitanOperationStatus operationStatus = parentResourceRes.right().value(); + + if (operationStatus != TitanOperationStatus.NOT_FOUND) { + return operationStatus; + } else { + return TitanOperationStatus.OK; + } + + } + + @SuppressWarnings("unchecked") + @Override + public Either updateComponent(T component, boolean inTransaction) { + return (Either) updateResource((Resource) component, inTransaction); + } + + @SuppressWarnings("unchecked") + @Override + public Either deleteComponent(String id, boolean inTransaction) { + return (Either) (Either) deleteResource(id, inTransaction); + } + + @Override + public Either getLatestByToscaResourceName(String toscaResourceName, boolean inTransaction) { + return getLatestByName(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), toscaResourceName, inTransaction); + + } + + @Override + public Either getLatestByName(String resourceName, boolean inTransaction) { + return getLatestByName(GraphPropertiesDictionary.NAME.getProperty(), resourceName, inTransaction); + + } + + private Either getLatestByName(String property, String resourceName, boolean inTransaction) { + Either result = null; + try { + Map props = new HashMap(); + props.put(property, resourceName); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either, TitanOperationStatus> highestResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (highestResources.isRight()) { + TitanOperationStatus status = highestResources.right().value(); + log.debug("failed to find resource with name {}. status={} ", resourceName, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List resources = highestResources.left().value(); + double version = 0.0; + ResourceMetadataData highestResource = null; + for (ResourceMetadataData resource : resources) { + double resourceVersion = Double.parseDouble(resource.getMetadataDataDefinition().getVersion()); + if (resourceVersion > version) { + version = resourceVersion; + highestResource = resource; + } + } + result = getResource(highestResource.getMetadataDataDefinition().getUniqueId(), true); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("getLatestByName operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("getLatestByName operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + + } + } + + @SuppressWarnings("unchecked") + @Override + public Either, StorageOperationStatus> getTesterFollowed(String userId, Set lifecycleStates, boolean inTransaction) { + return (Either, StorageOperationStatus>) (Either) getTesterFollowedComponent(userId, lifecycleStates, inTransaction, NodeTypeEnum.Resource); + } + + @Override + public Either, StorageOperationStatus> getResourceCatalogData(boolean inTransaction) { + return getResourceCatalogData(inTransaction, null); + } + + private Either, StorageOperationStatus> getResourceCatalogData(boolean inTransaction, Map otherToMatch) { + + long start = System.currentTimeMillis(); + + long startFetchAllStates = System.currentTimeMillis(); + Map propertiesToMatchHigest = new HashMap<>(); + propertiesToMatchHigest.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + propertiesToMatchHigest.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), false); + Either, TitanOperationStatus> allHighestStates = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatchHigest, ResourceMetadataData.class); + if (allHighestStates.isRight() && allHighestStates.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(allHighestStates.right().value())); + } + + if (allHighestStates.isRight()) { + return Either.left(new ArrayList<>()); + } + List list = allHighestStates.left().value(); + + List certified = new ArrayList<>(); + List noncertified = new ArrayList<>(); + for (ResourceMetadataData reData : list) { + if (reData.getMetadataDataDefinition().getState().equals(LifecycleStateEnum.CERTIFIED.name())) { + certified.add(reData); + } else { + noncertified.add(reData); + } + } + + long endFetchAll = System.currentTimeMillis(); + log.debug("Fetch catalog resources all states: certified {}, noncertified {}", certified.size(), noncertified.size()); + log.debug("Fetch catalog resources all states from graph took {} ms", endFetchAll - startFetchAllStates); + + try { + List notCertifiedHighest = noncertified; + List certifiedHighestList = certified; + + HashMap VFNames = new HashMap<>(); + HashMap VFCNames = new HashMap<>(); + for (ResourceMetadataData data : notCertifiedHighest) { + String serviceName = data.getMetadataDataDefinition().getName(); + if (((ResourceMetadataDataDefinition) data.getMetadataDataDefinition()).getResourceType().equals(ResourceTypeEnum.VF)) { + VFNames.put(serviceName, serviceName); + } else { + VFCNames.put(serviceName, serviceName); + } + } + + for (ResourceMetadataData data : certifiedHighestList) { + String serviceName = data.getMetadataDataDefinition().getName(); + if (((ResourceMetadataDataDefinition) data.getMetadataDataDefinition()).getResourceType().equals(ResourceTypeEnum.VF)) { + if (!VFNames.containsKey(serviceName)) { + notCertifiedHighest.add(data); + } + } else { + if (!VFCNames.containsKey(serviceName)) { + notCertifiedHighest.add(data); + } + } + } + + long endFetchAllFromGraph = System.currentTimeMillis(); + log.debug("Fetch all catalog resources metadata from graph took {} ms", endFetchAllFromGraph - start); + + long startFetchAllFromCache = System.currentTimeMillis(); + + List result = new ArrayList<>(); + + Map components = notCertifiedHighest.stream().collect(Collectors.toMap(p -> p.getMetadataDataDefinition().getUniqueId(), p -> p.getMetadataDataDefinition().getLastUpdateDate())); + + Either, Set>, ActionStatus> componentsForCatalog = componentCache.getComponentsForCatalog(components, ComponentTypeEnum.RESOURCE); + if (componentsForCatalog.isLeft()) { + ImmutablePair, Set> immutablePair = componentsForCatalog.left().value(); + List foundComponents = immutablePair.getLeft(); + if (foundComponents != null) { + foundComponents.forEach(p -> result.add((Resource) p)); + log.debug("The number of resources added to catalog from cache is {}", foundComponents.size()); + + List foundComponentsUid = foundComponents.stream().map(p -> p.getUniqueId()).collect(Collectors.toList()); + notCertifiedHighest = notCertifiedHighest.stream().filter(p -> false == foundComponentsUid.contains(p.getUniqueId())).collect(Collectors.toList()); + } + Set nonCachedComponents = immutablePair.getRight(); + int numberNonCached = nonCachedComponents == null ? 0 : nonCachedComponents.size(); + log.debug("The number of left resources for catalog is {}", numberNonCached); + + } + + long endFetchAllFromCache = System.currentTimeMillis(); + log.debug("Fetch all catalog resources metadata from cache took " + (endFetchAllFromCache - startFetchAllFromCache) + " ms"); + + long startFetchFromGraph = System.currentTimeMillis(); + log.debug("The number of resources needed to be fetch as light component is {}", notCertifiedHighest.size()); + for (ResourceMetadataData data : notCertifiedHighest) { + String uniqueId = data.getMetadataDataDefinition().getUniqueId(); + log.trace("Fetch catalog resource non cached {} {}", uniqueId, data.getMetadataDataDefinition().getName()); + Either component = getLightComponent(uniqueId, inTransaction); + if (component.isRight()) { + log.debug("Failed to get Service for id = " + data.getUniqueId() + " error : " + component.right().value() + " skip resource"); + } else { + result.add(component.left().value()); + } + } + long endFetchFromGraph = System.currentTimeMillis(); + log.debug("Fetch catalog resources from graph took " + (endFetchFromGraph - startFetchFromGraph) + " ms"); + + return Either.left(result); + + } finally { + long end = System.currentTimeMillis(); + log.debug("Fetch all catalog resources took {} ms", end - start); + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + public Either, StorageOperationStatus> getResourceCatalogDataVFLatestCertifiedAndNonCertified(boolean inTransaction) { + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + + return getResourceCatalogDataLatestCertifiedAndNonCertified(inTransaction, propertiesToMatch); + } + + private Either, StorageOperationStatus> getResourceCatalogDataLatestCertifiedAndNonCertified(boolean inTransaction, Map otherToMatch) { + Map propertiesToMatch = new HashMap<>(); + + if (otherToMatch != null) { + propertiesToMatch.putAll(otherToMatch); + } + + propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either, TitanOperationStatus> lastVersionNodes = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + + List result = new ArrayList<>(); + + if (lastVersionNodes.isRight() && lastVersionNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(lastVersionNodes.right().value())); + } + + List listOfHighest; + + if (lastVersionNodes.isLeft()) { + listOfHighest = lastVersionNodes.left().value(); + } else { + return Either.left(result); + } + + for (ResourceMetadataData data : listOfHighest) { + Either component = getLightComponent(data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get Service for id = " + data.getUniqueId() + " error : " + component.right().value() + " skip resource"); + } else { + result.add(component.left().value()); + } + } + return Either.left(result); + } + + private Either, StorageOperationStatus> getResourceListByCriteria(Map props, boolean inTransaction) { + + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()); + + Either, TitanOperationStatus> byCriteria = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List resources = new ArrayList(); + List resourcesDataList = byCriteria.left().value(); + for (ResourceMetadataData data : resourcesDataList) { + Either resource = getResource(data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (resource.isLeft()) { + resources.add(resource.left().value()); + } else { + log.debug("Failed to fetch resource for name = " + data.getMetadataDataDefinition().getName() + " and id = " + data.getUniqueId()); + } + } + return Either.left(resources); + } + + public Either, StorageOperationStatus> getResourceListByUuid(String uuid, boolean inTransaction) { + return getLatestResourceByUuid(uuid, false, inTransaction); + } + + public Either, StorageOperationStatus> getLatestResourceByUuid(String uuid, boolean inTransaction) { + return getLatestResourceByUuid(uuid, true, inTransaction); + } + + private Either, StorageOperationStatus> getLatestResourceByUuid(String uuid, boolean isLatest, boolean inTransaction) { + Map props = new HashMap(); + if (isLatest) { + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), isLatest); + } + props.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + return getResourceListByCriteria(props, inTransaction); + } + + public Either, StorageOperationStatus> getResourceListBySystemName(String systemName, boolean inTransaction) { + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + return getResourceListByCriteria(props, inTransaction); + } + + public Either, StorageOperationStatus> getResourceListByToscaName(String toscaName, boolean inTransaction) { + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), toscaName); + return getResourceListByCriteria(props, inTransaction); + } + + public Either, StorageOperationStatus> getResourceByNameAndVersion(String name, String version, boolean inTransaction) { + return getByNamesAndVersion(GraphPropertiesDictionary.NAME.getProperty(), name, version, null, inTransaction); + } + + @Override + public Either, StorageOperationStatus> getResourceByNameAndVersion(String name, String version) { + return getResourceByNameAndVersion(name, version, false); + } + + protected Either, StorageOperationStatus> getByNamesAndVersion(String nameKey, String nameValue, String version, Map additionalParams, boolean inTransaction) { + Map props = new HashMap(); + props.put(nameKey, nameValue); + props.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()); + if (additionalParams != null && !additionalParams.isEmpty()) { + props.putAll(additionalParams); + } + + Either, TitanOperationStatus> byCriteria = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + List resourcesList = new ArrayList(); + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List dataList = byCriteria.left().value(); + if (dataList != null && !dataList.isEmpty()) { + // if (dataList.size() > 1) { + // log.debug("More that one instance of resource for name =" + + // nameValue + " and version = " + version); + // return Either.right(StorageOperationStatus.GENERAL_ERROR); + // } + for (ResourceMetadataData resourceData : dataList) { + // ResourceMetadataData resourceData = dataList.get(0); + Either resource = getResource(resourceData.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (resource.isRight()) { + log.debug("Failed to fetch resource for name = " + resourceData.getMetadataDataDefinition().getName() + " and id = " + resourceData.getUniqueId()); + return Either.right(resource.right().value()); + } + resourcesList.add(resource.left().value()); + } + // return resource; + return Either.left(resourcesList); + } else { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + } + + @Override + protected Either getComponentByNameAndVersion(String name, String version, Map additionalParams, boolean inTransaction) { + return (Either) getResourceBySystemNameAndVersion(name, version, additionalParams, inTransaction); + } + + @Override + public Either getResourceBySystemNameAndVersion(String name, String version, Map additionalParams, boolean inTransaction) { + Either, StorageOperationStatus> byNamesAndVersion = getByNamesAndVersion(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normaliseComponentName(name), version, additionalParams, inTransaction); + if (byNamesAndVersion.isRight()) { + return Either.right(byNamesAndVersion.right().value()); + } + List resourcesList = byNamesAndVersion.left().value(); + if (resourcesList.size() > 1) { + log.debug("More that one instance of resource for name =" + name + " and version = " + version); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + return Either.left(resourcesList.get(0)); + } + + private TitanOperationStatus setAllVersions(Resource resource) { + Either, TitanOperationStatus> res = getVersionList(NodeTypeEnum.Resource, resource.getVersion(), resource, ResourceMetadataData.class); + if (res.isRight()) { + return res.right().value(); + } + resource.setAllVersions(res.left().value()); + return TitanOperationStatus.OK; + } + + @Override + protected Either, TitanOperationStatus> getVersionList(NodeTypeEnum type, String version, Component component, Class clazz) { + Map props = new HashMap(); + Map hasNotProps = new HashMap(); + + if (version.startsWith("0")) { + props.put(GraphPropertiesDictionary.UUID.getProperty(), component.getUUID()); + } else { + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), component.getSystemName()); + props.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ((Resource) component).getResourceType().name()); + } + hasNotProps.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), true); + Either, TitanOperationStatus> result = titanGenericDao.getByCriteria(type, props, hasNotProps, clazz); + + Map versionMap = new HashMap(); + if (result.isRight()) { + if (!result.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.right(result.right().value()); + } + + } else { + List components = (List) result.left().value(); + for (ResourceMetadataData data : components) { + versionMap.put(data.getMetadataDataDefinition().getVersion(), (String) data.getUniqueId()); + } + } + + return Either.left(versionMap); + } + + /** + * update only the resource object itself without tag, derived from or any other neighbours. + * + * @param resource + * @param inTransaction + * @return + */ + protected Either updateResourceMetadata(Resource resource, boolean inTransaction) { + + Either result = null; + + try { + + log.debug("In updateResource. received resource = " + (resource == null ? null : resource.toString())); + if (resource == null) { + log.error("Resource object is null"); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resource.getUniqueId()); + resourceData.getMetadataDataDefinition().setHighestVersion(resource.isHighestVersion()); + log.debug("After converting resource to ResourceData. ResourceData = " + resourceData); + + if (resourceData.getUniqueId() == null) { + log.error("Resource id is missing in the request."); + return Either.right(StorageOperationStatus.BAD_REQUEST); + } + + Either updateNode = titanGenericDao.updateNode(resourceData, ResourceMetadataData.class); + + if (updateNode.isRight()) { + log.error("Failed to update resource " + resource.getUniqueId() + ". status is " + updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + + Either updatedResource = getResource(resource.getUniqueId(), true); + if (updatedResource.isRight()) { + log.error("Resource id is missing in the request. status is " + updatedResource.right().value()); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + Resource updatedResourceValue = updatedResource.left().value(); + result = Either.left(updatedResourceValue); + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Resource retrieved after update is " + json); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either, StorageOperationStatus> getAllCertifiedResources(boolean isAbstract, Boolean isHighest) { + + try { + List result = new ArrayList<>(); + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), isAbstract); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + if (isHighest != null) { + propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), isHighest.booleanValue()); + } + + Either, TitanOperationStatus> resourceNodes = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + + titanGenericDao.commit(); + if (resourceNodes.isRight()) { + // in case of NOT_FOUND from Titan client return to UI empty + // list + if (resourceNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.left(result); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceNodes.right().value())); + } + } else { + List resourceDataList = resourceNodes.left().value(); + for (ResourceMetadataData resourceData : resourceDataList) { + Either resource = getResource(resourceData.getMetadataDataDefinition().getUniqueId()); + if (resource.isRight()) { + log.debug("Failed to fetch resource for id = " + resourceData.getUniqueId() + " error is " + resource.right().value()); + return Either.right(resource.right().value()); + } + result.add(resource.left().value()); + } + return Either.left(result); + } + } finally { + titanGenericDao.commit(); + } + + } + + public Either getLatestCertifiedByToscaResourceName(String toscaResourceName, boolean inTransaction) { + return getLatestCertifiedByCriteria(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), toscaResourceName, inTransaction); + + } + + public Either getLatestCertifiedByCriteria(String property, String resourceName, boolean inTransaction) { + Either result = null; + try { + Map props = new HashMap(); + props.put(property, resourceName); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + Either, TitanOperationStatus> highestResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (highestResources.isRight()) { + TitanOperationStatus status = highestResources.right().value(); + log.debug("failed to find resource with name {}. status={} ", resourceName, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List resources = highestResources.left().value(); + double version = 0.0; + ResourceMetadataData highestResource = null; + for (ResourceMetadataData resource : resources) { + double resourceVersion = Double.parseDouble(resource.getMetadataDataDefinition().getVersion()); + if (resourceVersion > version) { + version = resourceVersion; + highestResource = resource; + } + } + result = getResource(highestResource.getMetadataDataDefinition().getUniqueId(), true); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("getLatestByName operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("getLatestByName operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + + } + } + + public Either, StorageOperationStatus> findLastCertifiedResourceByName(Resource resource) { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), resource.getName()); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + return getResourceListByCriteria(props, false); + + } + + public Either, StorageOperationStatus> findLastCertifiedResourceByUUID(Resource resource) { + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.UUID.getProperty(), resource.getUUID()); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + return getResourceListByCriteria(props, false); + + } + + @Override + public boolean isComponentExist(String resourceId) { + return isComponentExist(resourceId, NodeTypeEnum.Resource); + } + + @Override + public Either cloneComponent(T other, String version, LifecycleStateEnum targetLifecycle, boolean inTransaction) { + return (Either) cloneResource((Resource) other, version, targetLifecycle, inTransaction); + } + + @Override + public Either increaseAndGetComponentInstanceCounter(String componentId, boolean inTransaction) { + return increaseAndGetComponentInstanceCounter(componentId, NodeTypeEnum.Resource, inTransaction); + } + + private Either cloneResource(Resource other, String version, boolean inTransaction) { + return cloneResource(other, version, null, inTransaction); + } + + private Either cloneResource(Resource other, String version, LifecycleStateEnum targetLifecycle, boolean inTransaction) { + Either result = null; + + try { + String origRsourceId = other.getUniqueId(); + + StorageOperationStatus overrideStatus = overrideRecursiveMembers(other, origRsourceId); + if (!overrideStatus.equals(StorageOperationStatus.OK)) { + return Either.right(overrideStatus); + } + other.setVersion(version); + other.setUniqueId(null); + + List inputs = other.getInputs(); + Map> inputsPropMap = new HashMap>(); + + if (inputs != null) { + for (InputDefinition input : inputs) { + + Either, TitanOperationStatus> inputPropStatus = inputOperation.getComponentInstancePropertiesByInputId(input.getUniqueId()); + if (inputPropStatus.isLeft()) { + if (inputPropStatus.left().value() != null) + inputsPropMap.put(input.getName(), inputPropStatus.left().value()); + + } + + } + } + + Either createResourceMD = createResource(other, inTransaction); + if (createResourceMD.isRight()) { + StorageOperationStatus status = createResourceMD.right().value(); + log.error("failed to clone resource. status= {}", status); + result = Either.right(status); + return result; + } + Resource resource = createResourceMD.left().value(); + Either metadataVertexEither = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resource.getUniqueId()); + if (metadataVertexEither.isRight()) { + TitanOperationStatus error = metadataVertexEither.right().value(); + log.debug("Failed to fetch vertex of metadata {} error {}", resource.getUniqueId(), error); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error)); + return result; + } + + TitanVertex metadataVertex = metadataVertexEither.left().value(); + Either, Map>, StorageOperationStatus> cloneInstances = componentInstanceOperation.cloneAllComponentInstancesFromContainerComponent(origRsourceId, resource.getUniqueId(), + NodeTypeEnum.Resource, NodeTypeEnum.Resource, targetLifecycle, metadataVertex, other, resource, inputsPropMap); + if (cloneInstances.isRight()) { + result = Either.right(cloneInstances.right().value()); + return result; + } + + Either counterStatus = getComponentInstanceCoutner(origRsourceId, NodeTypeEnum.Resource); + if (counterStatus.isRight()) { + StorageOperationStatus status = counterStatus.right().value(); + log.error("failed to get resource instance counter on service {}. status={}", origRsourceId, counterStatus); + result = Either.right(status); + return result; + } + + Either setResourceInstanceCounter = setComponentInstanceCounter(resource.getUniqueId(), NodeTypeEnum.Resource, counterStatus.left().value(), true); + if (setResourceInstanceCounter.isRight()) { + StorageOperationStatus status = setResourceInstanceCounter.right().value(); + log.error("failed to set resource instance counter on service {}. status={}", resource.getUniqueId(), status); + result = Either.right(status); + return result; + } + + Either, StorageOperationStatus> clonedGroups = cloneGroups(other, resource, cloneInstances.left().value(), true); + if (clonedGroups.isRight()) { + StorageOperationStatus status = clonedGroups.right().value(); + if (status != StorageOperationStatus.OK) { + result = Either.right(status); + return result; + } + } + + result = this.getResource(resource.getUniqueId(), true); + if (result.isRight()) { + log.error("Cannot get full service from the graph. status is " + result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + // log.debug("Resource retrieved is {}", json); + } + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus overrideRecursiveMembers(Resource resource, String prevId) { + // override requirements to copy only resource's requirements and not + // derived requirements + Either>, StorageOperationStatus> requirementsOfResourceOnly = getRequirementOperation().getAllRequirementsOfResourceOnly(prevId, true); + if (requirementsOfResourceOnly.isRight()) { + log.error("failed to get requirements of resource. resourceId {} status is {}", prevId, requirementsOfResourceOnly.right().value()); + return requirementsOfResourceOnly.right().value(); + } + resource.setRequirements(requirementsOfResourceOnly.left().value()); + + // override capabilities to copy only resource's requirements and not + // derived requirements + Either>, StorageOperationStatus> capabilitiesOfResourceOnly = getResourceCapabilitiesMap(prevId); + + resource.setCapabilities(capabilitiesOfResourceOnly.left().value()); + + // override interfaces to copy only resource's interfaces and not + // derived interfaces + Either, StorageOperationStatus> interfacesOfResourceOnly = getInterfaceLifecycleOperation().getAllInterfacesOfResource(prevId, false, true); + if (interfacesOfResourceOnly.isRight()) { + log.error("failed to get interfaces of resource. resourceId {} status is {}", prevId, interfacesOfResourceOnly.right().value()); + return interfacesOfResourceOnly.right().value(); + } + resource.setInterfaces(interfacesOfResourceOnly.left().value()); + + List attributes = new ArrayList<>(); + TitanOperationStatus status = attributeOperation.findNodeNonInheretedAttribues(prevId, NodeTypeEnum.Resource, attributes); + if (status != TitanOperationStatus.OK) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } else { + resource.setAttributes(attributes); + } + + // override properties to copy only resource's properties and not + // derived properties + Either, TitanOperationStatus> propertiesOfResourceOnly = getPropertyOperation().findPropertiesOfNode(NodeTypeEnum.Resource, prevId); + + List resourceProperties = null; + if (propertiesOfResourceOnly.isRight()) { + TitanOperationStatus titanStatus = propertiesOfResourceOnly.right().value(); + if (titanStatus != TitanOperationStatus.NOT_FOUND) { + log.error("failed to get properties of resource. resourceId {} status is {}", prevId, propertiesOfResourceOnly.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + } else { + Map propertiesMap = propertiesOfResourceOnly.left().value(); + if (propertiesMap != null) { + resourceProperties = new ArrayList(); + resourceProperties.addAll(propertiesMap.values()); + } + } + resource.setProperties(resourceProperties); + + return StorageOperationStatus.OK; + } + + private Either>, StorageOperationStatus> getResourceCapabilitiesMap(String prevId) { + + Either, StorageOperationStatus> capabilitiesOfResourceOnly = getCapabilityOperation().getAllCapabilitiesOfResource(prevId, false, true); + if (capabilitiesOfResourceOnly.isRight()) { + log.error("failed to get capabilities of resource. resourceId {} status is {}", prevId, capabilitiesOfResourceOnly.right().value()); + return Either.right(capabilitiesOfResourceOnly.right().value()); + } + Map> capabilityMap = getCapabilityOperation().convertCapabilityMap(capabilitiesOfResourceOnly.left().value(), null, null); + return Either.left(capabilityMap); + } + + @Override + protected StorageOperationStatus validateCategories(Component currentComponent, Component component, ComponentMetadataData componentData, NodeTypeEnum type) { + StorageOperationStatus status = StorageOperationStatus.OK; + List newCategoryList = component.getCategories(); + CategoryDefinition newCategory = newCategoryList.get(0); + CategoryDefinition currentCategory = currentComponent.getCategories().get(0); + boolean categoryWasChanged = false; + + if (newCategory.getName() != null && false == newCategory.getName().equals(currentCategory.getName())) { + // the category was changed + categoryWasChanged = true; + } else { + // the sub-category was changed + SubCategoryDefinition currSubcategory = currentCategory.getSubcategories().get(0); + SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0); + if (newSubcategory.getName() != null && false == newSubcategory.getName().equals(currSubcategory.getName())) { + log.debug("Going to update the category of the resource from " + currentCategory + " to " + newCategory); + categoryWasChanged = true; + } + } + if (categoryWasChanged) { + status = moveCategoryEdge((Resource) component, (ResourceMetadataData) componentData, newCategory); + log.debug("Going to update the category of the resource from " + currentCategory + " to " + newCategory + ". status is " + status); + } + return status; + } + + @Override + public Resource getDefaultComponent() { + return new Resource(); + } + + @Override + public Either getMetadataComponent(String id, boolean inTransaction) { + return getMetadataComponent(id, NodeTypeEnum.Resource, inTransaction); + } + + @Override + Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) { + return convertResourceDataToResource((ResourceMetadataData) componentMetadataData); + } + + @Override + public Either validateComponentNameExists(String componentName) { + return validateComponentNameUniqueness(componentName, titanGenericDao, NodeTypeEnum.Resource); + } + + @Override + public Either markComponentToDelete(Component componentToDelete, boolean inTransaction) { + return internalMarkComponentToDelete(componentToDelete, inTransaction); + } + + @Override + public Either isComponentInUse(String componentId) { + return isResourceInUse(componentId); + } + + @Override + public Either, StorageOperationStatus> getAllComponentsMarkedForDeletion() { + return getAllResourcesMarkedForDeletion(); + } + + @Override + public Either, StorageOperationStatus> getAllResourcesMarkedForDeletion() { + return getAllComponentsMarkedForDeletion(NodeTypeEnum.Resource); + } + + @Override + public Either isResourceInUse(String resourceToDelete) { + return isComponentInUse(resourceToDelete, NodeTypeEnum.Resource); + } + + public Either, StorageOperationStatus> cloneGroups(Resource resource, Resource newResource, ImmutablePair, Map> cloneInstances, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + if (resource.getGroups() == null) { + return Either.right(StorageOperationStatus.OK); + } + + Either, StorageOperationStatus> prepareGroupsForCloning = groupOperation.prepareGroupsForCloning(resource, cloneInstances); + if (prepareGroupsForCloning.isRight()) { + StorageOperationStatus status = prepareGroupsForCloning.right().value(); + if (status != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("CloneResource", "Failed to prepare groups for cloning", ErrorSeverity.ERROR); + } + result = Either.right(status); + return result; + } else { + List groupsToCreate = prepareGroupsForCloning.left().value(); + if (groupsToCreate != null && false == groupsToCreate.isEmpty()) { + Either, StorageOperationStatus> addGroups = groupOperation.addGroups(NodeTypeEnum.Resource, newResource.getUniqueId(), groupsToCreate, inTransaction); + if (addGroups.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("CloneResource", "Failed to clone groups", ErrorSeverity.ERROR); + result = Either.right(addGroups.right().value()); + return result; + } + + return Either.left(addGroups.left().value()); + } else { + return Either.right(StorageOperationStatus.OK); + } + } + } + + public Either getLatestResourceByCsarOrName(String csarUUID, String systemName) { + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CSAR_UUID.getProperty(), csarUUID); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + ResourceMetadataData resourceMetadataData = null; + List resourceMetadataDataList = null; + Either, TitanOperationStatus> byCsar = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (byCsar.isRight()) { + if (TitanOperationStatus.NOT_FOUND.equals(byCsar.right().value())) { + props.clear(); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + Either, TitanOperationStatus> bySystemname = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (bySystemname.isRight()) { + log.debug("getLatestResourceByCsarOrName - Failed to find by system name {} error {} ", systemName, bySystemname.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(bySystemname.right().value())); + } + if (bySystemname.left().value().size() > 2) { + log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) must return only 2 latest version, but was returned - " + bySystemname.left().value().size()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + resourceMetadataDataList = bySystemname.left().value(); + if (resourceMetadataDataList.size() == 1) { + resourceMetadataData = resourceMetadataDataList.get(0); + } else { + for (ResourceMetadataData curResource : resourceMetadataDataList) { + if (!curResource.getMetadataDataDefinition().getState().equals("CERTIFIED")) { + resourceMetadataData = curResource; + break; + } + } + } + if (resourceMetadataData == null) { + log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) returned 2 latest CERTIFIED versions"); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + if (resourceMetadataData.getMetadataDataDefinition().getCsarUUID() != null && !resourceMetadataData.getMetadataDataDefinition().getCsarUUID().equals(csarUUID)) { + log.debug("getLatestResourceByCsarOrName - same system name {} but different csarUUID. exist {} and new {} ", systemName, resourceMetadataData.getMetadataDataDefinition().getCsarUUID(), csarUUID); + // correct error will be returned from create flow. with all + // correct audit records!!!!! + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Either resource = getResource((String) resourceMetadataData.getUniqueId()); + return resource; + } + } else { + resourceMetadataDataList = byCsar.left().value(); + if (resourceMetadataDataList.size() > 2) { + log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) must return only 2 latest version, but was returned - " + byCsar.left().value().size()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + if (resourceMetadataDataList.size() == 1) { + resourceMetadataData = resourceMetadataDataList.get(0); + } else { + for (ResourceMetadataData curResource : resourceMetadataDataList) { + if (!curResource.getMetadataDataDefinition().getState().equals("CERTIFIED")) { + resourceMetadataData = curResource; + break; + } + } + } + if (resourceMetadataData == null) { + log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) returned 2 latest CERTIFIED versions"); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Either resource = getResource((String) resourceMetadataData.getMetadataDataDefinition().getUniqueId()); + return resource; + } + return null; + } + + public Either, StorageOperationStatus> validateCsarUuidUniqueness(String csarUUID) { + + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CSAR_UUID.getProperty(), csarUUID); + + Either, TitanOperationStatus> byCsar = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (byCsar.isRight()) { + if (TitanOperationStatus.NOT_FOUND.equals(byCsar.right().value())) { + return Either.left(null); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCsar.right().value())); + } + } + return Either.left(byCsar.left().value()); + } + + private Either getResource(String uniqueId, ComponentParametersView componentParametersView, boolean inTransaction) { + + Resource resource = null; + try { + + NodeTypeEnum resourceNodeType = NodeTypeEnum.Resource; + NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + + Either componentByLabelAndId = getComponentByLabelAndId(uniqueId, resourceNodeType, ResourceMetadataData.class); + if (componentByLabelAndId.isRight()) { + return Either.right(componentByLabelAndId.right().value()); + } + ResourceMetadataData resourceData = componentByLabelAndId.left().value(); + + // Try to fetch resource from the cache. The resource will be + // fetched only if the time on the cache equals to + // the time on the graph. + Either componentFromCacheIfUpToDate = this.getComponentFromCacheIfUpToDate(uniqueId, resourceData, componentParametersView, Resource.class, ComponentTypeEnum.RESOURCE); + if (componentFromCacheIfUpToDate.isLeft()) { + Resource cachedResource = componentFromCacheIfUpToDate.left().value(); + log.debug("Resource {} with uid {} was fetched from cache.", cachedResource.getName(), cachedResource.getUniqueId()); + return Either.left(cachedResource); + } + + resource = convertResourceDataToResource(resourceData); + + TitanOperationStatus status = null; + if (false == componentParametersView.isIgnoreUsers()) { + status = setResourceCreatorFromGraph(resource, uniqueId); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + status = setResourceLastModifierFromGraph(resource, uniqueId); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreProperties()) { + status = setResourcePropertiesFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreAttributesFrom()) { + status = setResourceAttributesFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreDerivedFrom()) { + status = setResourceDerivedFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreCategories()) { + status = setComponentCategoriesFromGraph(resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + // Since capabilities and requirements and instances properties are + // based on component instances, then we must fetch the instances. + if (false == componentParametersView.isIgnoreComponentInstances() || false == componentParametersView.isIgnoreComponentInstancesProperties() || false == componentParametersView.isIgnoreComponentInstancesInputs() + || false == componentParametersView.isIgnoreCapabilities() || false == componentParametersView.isIgnoreRequirements()) { + + status = setComponentInstancesFromGraph(uniqueId, resource, resourceNodeType, compInstNodeType); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + if (false == componentParametersView.isIgnoreRequirements()) { + StorageOperationStatus setRequirementsStatus = setResourceRequirementsFromGraph(uniqueId, resource, true); + if (setRequirementsStatus != StorageOperationStatus.OK) { + log.error("Failed to set requirement of resource " + uniqueId + ". status is " + setRequirementsStatus); + return Either.right(setRequirementsStatus); + } + } + + if (false == componentParametersView.isIgnoreInputs()) { + status = setComponentInputsFromGraph(uniqueId, resource, true); + if (status != TitanOperationStatus.OK) { + log.error("Failed to set inputs of resource " + uniqueId + ". status is " + status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } + + StorageOperationStatus storageStatus = null; + if (false == componentParametersView.isIgnoreCapabilities()) { + storageStatus = setResourceCapabilitiesFromGraph(uniqueId, resource); + if (storageStatus != StorageOperationStatus.OK) { + return Either.right(storageStatus); + } + } + + if (false == componentParametersView.isIgnoreArtifacts()) { + storageStatus = setArtifactFromGraph(uniqueId, resource); + if (storageStatus != StorageOperationStatus.OK) { + return Either.right(storageStatus); + } + } + if (false == componentParametersView.isIgnoreComponentInstancesAttributesFrom()) { + status = setComponentInstancesAttributesFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + if (false == componentParametersView.isIgnoreComponentInstancesProperties()) { + status = setComponentInstancesPropertiesFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + if (false == componentParametersView.isIgnoreComponentInstancesInputs()) { + status = setComponentInstancesInputsFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + if (false == componentParametersView.isIgnoreInterfaces()) { + storageStatus = setResourceInterfacesFromGraph(uniqueId, resource); + if (storageStatus != StorageOperationStatus.OK) { + return Either.right(storageStatus); + } + } + + if (false == componentParametersView.isIgnoreAdditionalInformation()) { + storageStatus = setResourceAdditionalInformationFromGraph(uniqueId, resource); + if (storageStatus != StorageOperationStatus.OK) { + return Either.right(storageStatus); + } + } + + if (false == componentParametersView.isIgnoreAllVersions()) { + status = setAllVersions(resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreGroups()) { + status = setGroupsFromGraph(uniqueId, resource, NodeTypeEnum.Resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (true == componentParametersView.isIgnoreComponentInstances()) { + resource.setComponentInstances(null); + resource.setComponentInstancesRelations(null); + } + + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + + return Either.left(resource); + + } + + @SuppressWarnings("unchecked") + @Override + public Either getComponent(String id, ComponentParametersView componentParametersView, boolean inTrasnaction) { + + Either component = getResource(id, componentParametersView, inTrasnaction); + if (component.isRight()) { + return Either.right(component.right().value()); + } + return (Either) component; + } + + // @Override + public Either updateResource(Resource resource, boolean inTransaction, ComponentParametersView filterResultView) { + return (Either) updateComponentFilterResult(resource, inTransaction, titanGenericDao, resource.getClass(), NodeTypeEnum.Resource, filterResultView); + } + + @Override + protected Either updateComponentFilterResult(T component, boolean inTransaction, ComponentParametersView filterResultView) { + return (Either) updateResource((Resource) component, inTransaction, filterResultView); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperation.java new file mode 100644 index 0000000000..18229f9245 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperation.java @@ -0,0 +1,1566 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.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.function.Predicate; +import java.util.stream.Collectors; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.tuple.ImmutablePair; +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.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; +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.model.AdditionalInformationDefinition; +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.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.ServiceMetadataDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +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.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.thinkaurelius.titan.core.TitanGraph; + +import fj.data.Either; + +@org.springframework.stereotype.Component("service-operation") +public class ServiceOperation extends ComponentOperation implements IServiceOperation { + + private static Logger log = LoggerFactory.getLogger(ServiceOperation.class.getName()); + + @Resource + private IArtifactOperation artifactOperation; + + @Resource + private IElementOperation elementOperation; + + public ServiceOperation() { + log.debug("ServiceOperation created"); + } + + @Override + public Either createService(Service service) { + return createService(service, false); + } + + @Override + public Either createService(Service service, boolean inTransaction) { + Either result = null; + + try { + + ServiceMetadataData serviceData = getServiceMetaDataFromService(service); + addComponentInternalFields(serviceData); + String uniqueId = (String) serviceData.getUniqueId(); + generateUUID(service); + + String userId = service.getCreatorUserId(); + + Either findUser = findUser(userId); + + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } + + UserData creatorUserData = findUser.left().value(); + UserData updaterUserData = creatorUserData; + String updaterUserId = service.getLastUpdaterUserId(); + if (updaterUserId != null && !updaterUserId.equals(userId)) { + findUser = findUser(updaterUserId); + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } else { + updaterUserData = findUser.left().value(); + } + } + + // get category + List categories = service.getCategories(); + CategoryData categoryData = null; + + String categoryName = categories.get(0).getName(); + if (categoryName != null) { + Either categoryResult = elementOperation + .getNewCategoryData(categoryName, NodeTypeEnum.ServiceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + StorageOperationStatus status = categoryResult.right().value(); + /* + * TitanOperationStatus titanStatus = null; + * if(ActionStatus.CATEGORY_NOT_FOUND.equals(status)){ + * titanStatus = TitanOperationStatus.NOT_FOUND; }else{ + * titanStatus = TitanOperationStatus.GENERAL_ERROR; } + */ + log.error("Cannot find category " + categoryName + " in the graph. status is " + status); + return Either.right(status); + } + + categoryData = categoryResult.left().value(); + } + + StorageOperationStatus storageOperationStatus = createTagsForComponent(service); + if (storageOperationStatus != StorageOperationStatus.OK) { + return Either.right(storageOperationStatus); + } + + log.debug("try to create service node on graph for id " + serviceData.getUniqueId()); + Either createNode = titanGenericDao.createNode(serviceData, + ServiceMetadataData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Error returned after creating service data node " + serviceData + ". status returned is " + + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + log.debug("create service node created on graph for id " + serviceData.getUniqueId()); + + TitanOperationStatus associateMetadata = associateMetadataToComponent(serviceData, creatorUserData, + updaterUserData, null, null); + if (associateMetadata != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateMetadata)); + return result; + } + TitanOperationStatus associateCategory = associateMetadataCategoryToComponent(serviceData, categoryData); + if (associateCategory != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateCategory)); + return result; + } + + Map allArtifacts = new HashMap(); + if (service.getArtifacts() != null) { + allArtifacts.putAll(service.getArtifacts()); + } + if (service.getDeploymentArtifacts() != null) { + allArtifacts.putAll(service.getDeploymentArtifacts()); + } + if (service.getServiceApiArtifacts() != null) { + allArtifacts.putAll(service.getServiceApiArtifacts()); + } + if (service.getToscaArtifacts() != null) { + allArtifacts.putAll(service.getToscaArtifacts()); + } + + StorageOperationStatus associateArtifacts = associateArtifactsToComponent(NodeTypeEnum.Service, serviceData, + allArtifacts); + if (associateArtifacts != StorageOperationStatus.OK) { + result = Either.right(associateArtifacts); + return result; + } + + TitanOperationStatus associateInputs = associateInputsToComponent(NodeTypeEnum.Service, serviceData, + service.getInputs()); + if (associateInputs != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateInputs)); + return result; + } + + List additionalInformation = service.getAdditionalInformation(); + StorageOperationStatus addAdditionalInformation = addAdditionalInformationToService(uniqueId, + additionalInformation); + if (addAdditionalInformation != StorageOperationStatus.OK) { + result = Either.right(addAdditionalInformation); + return result; + } + + result = this.getService(uniqueId, true); + if (result.isRight()) { + log.error("Cannot get full service from the graph. status is " + result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Service retrieved is " + json); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private TitanOperationStatus associateMetadataCategoryToComponent(ServiceMetadataData serviceData, + CategoryData categoryData) { + Either result; + if (categoryData != null) { + result = titanGenericDao.createRelation(serviceData, categoryData, GraphEdgeLabels.CATEGORY, null); + log.debug("After associating component " + serviceData.getUniqueId() + " to category " + categoryData + + ". Edge type is " + GraphEdgeLabels.CATEGORY); + if (result.isRight()) { + log.error("Faield to associate component " + serviceData.getUniqueId() + " to category " + categoryData + + ". Edge type is " + GraphEdgeLabels.CATEGORY); + return result.right().value(); + } + } + return TitanOperationStatus.OK; + } + + private StorageOperationStatus addAdditionalInformationToService(String resourceUniqueId, + List additionalInformation) { + + StorageOperationStatus result = null; + + if (additionalInformation == null || true == additionalInformation.isEmpty()) { + result = super.addAdditionalInformation(NodeTypeEnum.Service, resourceUniqueId, null); + } else { + if (additionalInformation.size() == 1) { + result = super.addAdditionalInformation(NodeTypeEnum.Service, resourceUniqueId, + additionalInformation.get(0)); + } else { + result = StorageOperationStatus.BAD_REQUEST; + log.info( + "Cannot create resource with more than one additional information object. The number of received object is " + + additionalInformation.size()); + } + } + return result; + } + + public Either cloneService(Service other, String version, boolean inTransaction) { + return cloneService(other, version, null, inTransaction); + } + + public Either cloneService(Service other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + Either result = null; + + try { + String origServiceId = other.getUniqueId(); + other.setVersion(version); + other.setUniqueId(null); + + Either counterStatus = getComponentInstanceCoutner(origServiceId, + NodeTypeEnum.Service); + if (counterStatus.isRight()) { + StorageOperationStatus status = counterStatus.right().value(); + log.error("failed to get resource instance counter on service {}. status={}", origServiceId, + counterStatus); + result = Either.right(status); + return result; + } + Map> inputsValuesMap = new HashMap>(); + List inputs = other.getInputs(); + if(inputs != null){ + for(InputDefinition input: inputs){ + + Either, TitanOperationStatus> inputStatus = inputOperation.getComponentInstanceInputsByInputId(input.getUniqueId()); + + if(inputStatus.isLeft()){ + if(inputStatus.left().value() != null) + inputsValuesMap.put(input.getName(), inputStatus.left().value()); + } + } + } + + Either createServiceMD = createService(other, true); + + if (createServiceMD.isRight()) { + StorageOperationStatus status = createServiceMD.right().value(); + log.error("failed to clone service. status= {}", status); + result = Either.right(status); + return result; + } + + Service service = createServiceMD.left().value(); + + Either, Map>, StorageOperationStatus> cloneInstances = componentInstanceOperation.cloneAllComponentInstancesFromContainerComponent(origServiceId, service, + NodeTypeEnum.Service, NodeTypeEnum.Resource, targetLifecycle, inputsValuesMap); + if (cloneInstances.isRight()) { + result = Either.right(cloneInstances.right().value()); + return result; + } + + Either setResourceInstanceCounter = setComponentInstanceCounter( + service.getUniqueId(), NodeTypeEnum.Service, counterStatus.left().value(), true); + if (setResourceInstanceCounter.isRight()) { + StorageOperationStatus status = setResourceInstanceCounter.right().value(); + log.error("failed to set resource instance counter on service {}. status={}", service.getUniqueId(), + setResourceInstanceCounter); + result = Either.right(status); + return result; + } + + result = this.getService(service.getUniqueId(), true); + if (result.isRight()) { + log.error("Cannot get full service from the graph. status is " + result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isTraceEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.trace("Resource retrieved is {}", json); + } + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private ServiceMetadataData getServiceMetaDataFromService(Service service) { + ServiceMetadataData serviceData = new ServiceMetadataData( + (ServiceMetadataDataDefinition) service.getComponentMetadataDefinition().getMetadataDataDefinition()); + if (service.getNormalizedName() == null || service.getNormalizedName().isEmpty()) { + serviceData.getMetadataDataDefinition() + .setNormalizedName(ValidationUtils.normaliseComponentName(service.getName())); + } + if (service.getSystemName() == null || service.getSystemName().isEmpty()) { + serviceData.getMetadataDataDefinition() + .setSystemName(ValidationUtils.convertToSystemName(service.getName())); + } + + return serviceData; + } + + private Either sendError(TitanOperationStatus status, + StorageOperationStatus statusIfNotFound) { + Either result; + if (status == TitanOperationStatus.NOT_FOUND) { + result = Either.right(statusIfNotFound); + return result; + } else { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + /** + * + */ + public Either getService(String uniqueId) { + return getService(uniqueId, false); + } + + public Either getService(String uniqueId, boolean inTransaction) { + ComponentParametersView componentParametersView = new ComponentParametersView(); + return getService(uniqueId, componentParametersView, inTransaction); + } + // public Either getService(String + // uniqueId, boolean inTransaction) { + // + // Service service = null; + // Either result = null; + // try { + // + // NodeTypeEnum serviceNodeType = NodeTypeEnum.Service; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + // + // Either getComponentByLabel = + // getComponentByLabelAndId(uniqueId, serviceNodeType, + // ServiceMetadataData.class); + // if (getComponentByLabel.isRight()) { + // result = Either.right(getComponentByLabel.right().value()); + // return result; + // } + // ServiceMetadataData serviceData = getComponentByLabel.left().value(); + // service = convertServiceDataToService(serviceData); + // + // TitanOperationStatus status = setComponentCreatorFromGraph(service, + // uniqueId, serviceNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setComponentLastModifierFromGraph(service, uniqueId, + // serviceNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // status = setComponentCategoriesFromGraph(service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // // status = setServicePropertiesFromGraph(uniqueId, resource, vertex); + // // if (status != TitanOperationStatus.OK) { + // // return + // Either.right(TitanStatusConverter.convertTitanStatusToStorageStatus(status)); + // // } + // + // StorageOperationStatus storageStatus = setArtifactFromGraph(uniqueId, + // service, serviceNodeType, artifactOperation); + // if (storageStatus != StorageOperationStatus.OK) { + // result = Either.right(storageStatus); + // return result; + // } + // + // status = setComponentInstancesFromGraph(uniqueId, service, + // serviceNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setCapabilitiesFromGraph(uniqueId, service, + // NodeTypeEnum.Service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setRequirementsFromGraph( uniqueId, service, + // NodeTypeEnum.Service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setAllVersions(service); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setServiceAdditionalInformationFromGraph(uniqueId, service); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setGroupsFromGraph(uniqueId, service, NodeTypeEnum.Resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // result = Either.left(service); + // return result; + // } finally { + // if (false == inTransaction) { + // if (result == null || result.isRight()) { + // titanGenericDao.rollback(); + // } else { + // titanGenericDao.commit(); + // } + // } + // } + // } + + public Either getService(String uniqueId, + ComponentParametersView componentParametersView, boolean inTransaction) { + + Service service = null; + Either result = null; + try { + + NodeTypeEnum serviceNodeType = NodeTypeEnum.Service; + NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + + Either getComponentByLabel = getComponentByLabelAndId(uniqueId, + serviceNodeType, ServiceMetadataData.class); + if (getComponentByLabel.isRight()) { + result = Either.right(getComponentByLabel.right().value()); + return result; + } + ServiceMetadataData serviceData = getComponentByLabel.left().value(); + // Try to fetch resource from the cache. The resource will be + // fetched only if the time on the cache equals to + // the time on the graph. + Either componentFromCacheIfUpToDate = this.getComponentFromCacheIfUpToDate(uniqueId, + serviceData, componentParametersView, Service.class, ComponentTypeEnum.SERVICE); + if (componentFromCacheIfUpToDate.isLeft()) { + Service cachedService = componentFromCacheIfUpToDate.left().value(); + log.debug("Service {} with uid {} was fetched from cache.", cachedService.getName(), + cachedService.getUniqueId()); + return Either.left(cachedService); + } + + service = convertServiceDataToService(serviceData); + TitanOperationStatus status = null; + if (false == componentParametersView.isIgnoreUsers()) { + status = setComponentCreatorFromGraph(service, uniqueId, serviceNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + status = setComponentLastModifierFromGraph(service, uniqueId, serviceNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + if (false == componentParametersView.isIgnoreCategories()) { + status = setComponentCategoriesFromGraph(service); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + + // status = setServicePropertiesFromGraph(uniqueId, resource, + // vertex); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(TitanStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + + if (false == componentParametersView.isIgnoreArtifacts()) { + StorageOperationStatus storageStatus = setArtifactFromGraph(uniqueId, service, serviceNodeType, + artifactOperation); + if (storageStatus != StorageOperationStatus.OK) { + result = Either.right(storageStatus); + return result; + } + } + + if (false == componentParametersView.isIgnoreComponentInstances() + || false == componentParametersView.isIgnoreComponentInstancesProperties() + || false == componentParametersView.isIgnoreCapabilities() + || false == componentParametersView.isIgnoreRequirements()) { + status = setComponentInstancesFromGraph(uniqueId, service, serviceNodeType, compInstNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + if (false == componentParametersView.isIgnoreComponentInstancesProperties()) { + status = setComponentInstancesPropertiesFromGraph(uniqueId, service); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreCapabilities()) { + status = setCapabilitiesFromGraph(uniqueId, service, NodeTypeEnum.Service); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreRequirements()) { + status = setRequirementsFromGraph(uniqueId, service, NodeTypeEnum.Service); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreAllVersions()) { + status = setAllVersions(service); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + if (false == componentParametersView.isIgnoreAdditionalInformation()) { + status = setServiceAdditionalInformationFromGraph(uniqueId, service); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreGroups()) { + status = setGroupsFromGraph(uniqueId, service, NodeTypeEnum.Resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + if (false == componentParametersView.isIgnoreInputs()) { + status = setComponentInputsFromGraph(uniqueId, service, true); + if (status != TitanOperationStatus.OK) { + log.error("Failed to set inputs of resource " + uniqueId + ". status is " + status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } + + if (false == componentParametersView.isIgnoreComponentInstancesInputs()) { + status = setComponentInstancesInputsFromGraph(uniqueId, service); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + result = Either.left(service); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + } + + // public Either getService_tx(String + // uniqueId, boolean inTransaction) { + // + // Service service = null; + // Either result = null; + // try { + // + // NodeTypeEnum serviceNodeType = NodeTypeEnum.Service; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + // + // Either getComponentByLabel = + // getComponentByLabelAndId_tx(uniqueId, serviceNodeType, + // ServiceMetadataData.class); + // if (getComponentByLabel.isRight()) { + // result = Either.right(getComponentByLabel.right().value()); + // return result; + // } + // ServiceMetadataData serviceData = getComponentByLabel.left().value(); + // service = convertServiceDataToService(serviceData); + // + // TitanOperationStatus status = setComponentCreatorFromGraph(service, + // uniqueId, serviceNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setComponentLastModifierFromGraph(service, uniqueId, + // serviceNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // status = setComponentCategoriesFromGraph(service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // // status = setServicePropertiesFromGraph(uniqueId, resource, vertex); + // // if (status != TitanOperationStatus.OK) { + // // return + // Either.right(TitanStatusConverter.convertTitanStatusToStorageStatus(status)); + // // } + // + // StorageOperationStatus storageStatus = setArtifactFromGraph(uniqueId, + // service, serviceNodeType, artifactOperation); + // if (storageStatus != StorageOperationStatus.OK) { + // result = Either.right(storageStatus); + // return result; + // } + // + // status = setComponentInstancesFromGraph(uniqueId, service, + // serviceNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setCapabilitiesFromGraph(uniqueId, service, + // NodeTypeEnum.Service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setRequirementsFromGraph( uniqueId, service, + // NodeTypeEnum.Service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setAllVersions(service); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setServiceAdditionalInformationFromGraph(uniqueId, service); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // result = Either.left(service); + // return result; + // } finally { + // if (false == inTransaction) { + // if (result == null || result.isRight()) { + // titanGenericDao.rollback(); + // } else { + // titanGenericDao.commit(); + // } + // } + // } + // } + + @Override + TitanOperationStatus setComponentCategoriesFromGraph(Component service) { + + String uniqueId = service.getUniqueId(); + Either>, TitanOperationStatus> parentNode = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), uniqueId, + GraphEdgeLabels.CATEGORY, NodeTypeEnum.ServiceNewCategory, CategoryData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + List> listValue = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Result after looking for category nodes pointed by service {}. status is {}", uniqueId, + listValue); + if (listValue.size() > 1) { + log.error("Multiple edges foud between resource " + uniqueId + " to category nodes."); + } + ImmutablePair value = listValue.get(0); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + + CategoryData categoryData = value.getKey(); + CategoryDefinition categoryDefinition = new CategoryDefinition(categoryData.getCategoryDataDefinition()); + + List categories = new ArrayList<>(); + categories.add(categoryDefinition); + service.setCategories(categories); + return TitanOperationStatus.OK; + + } + + @Override + public Either deleteService(String serviceId) { + return deleteService(serviceId, false); + } + + @Override + public Either deleteService(String serviceId, boolean inTransaction) { + + Either result = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + + Either serviceNode = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), serviceId, ServiceMetadataData.class); + if (serviceNode.isRight()) { + TitanOperationStatus status = serviceNode.right().value(); + log.error("Failed to find service " + serviceId + ". status is " + status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + Either serviceRes = getService(serviceId, true); + if (serviceRes.isRight()) { + StorageOperationStatus status = serviceRes.right().value(); + log.error("Failed to find sevice " + serviceId + ".status is " + status); + result = Either.right(status); + return result; + } + Service service = serviceRes.left().value(); + + Either, StorageOperationStatus> deleteAllResourceInstancesRes = componentInstanceOperation + .deleteAllComponentInstances(serviceId, NodeTypeEnum.Service, true); + log.debug("After deleting resource instances under service " + serviceId + ".Result is " + + deleteAllResourceInstancesRes); + if (deleteAllResourceInstancesRes.isRight()) { + StorageOperationStatus status = deleteAllResourceInstancesRes.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + log.error( + "Failed to delete resource instances under service " + serviceId + " .status is " + status); + result = Either.right(status); + return result; + } + } + StorageOperationStatus removeArtifactsFromResource = removeArtifactsFromComponent(service, + NodeTypeEnum.Service); + log.debug("After deleting artifacts nodes in the graph. status is " + removeArtifactsFromResource); + if (!removeArtifactsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeArtifactsFromResource); + return result; + } + + StorageOperationStatus removeInputsFromResource = removeInputsFromComponent(NodeTypeEnum.Service, service); + log.debug("After deleting requirements nodes in the graph. status is " + removeInputsFromResource); + if (removeInputsFromResource != StorageOperationStatus.OK) { + result = Either.right(removeInputsFromResource); + return result; + } + + Either>, TitanOperationStatus> deleteChildrenNodesRes = titanGenericDao + .deleteChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), serviceId, + GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property, PropertyData.class); + + if (deleteChildrenNodesRes.isRight()) { + TitanOperationStatus status = deleteChildrenNodesRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + StorageOperationStatus removeAdditionalInformationFromService = super.deleteAdditionalInformation( + NodeTypeEnum.Service, serviceId); + log.debug("After deleting additional information node in the graph. status is " + + removeAdditionalInformationFromService); + if (!removeAdditionalInformationFromService.equals(StorageOperationStatus.OK)) { + result = Either.right(removeAdditionalInformationFromService); + return result; + } + + StorageOperationStatus removeGroupsFromService = super.deleteGroups(NodeTypeEnum.Service, serviceId); + log.debug("After deleting group nodes in the graph. status is " + removeGroupsFromService); + if (!removeGroupsFromService.equals(StorageOperationStatus.OK)) { + result = Either.right(removeGroupsFromService); + return result; + } + + Either deleteServiceNodeRes = titanGenericDao + .deleteNode(serviceNode.left().value(), ServiceMetadataData.class); + if (deleteServiceNodeRes.isRight()) { + TitanOperationStatus status = deleteServiceNodeRes.right().value(); + log.error("Failed to delete service node " + serviceId + ". status is " + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + result = Either.left(service); + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("deleteService operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("deleteService operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either validateServiceNameExists(String serviceName) { + return validateServiceNameUniqueness(serviceName, titanGenericDao); + } + + private Service convertServiceDataToService(ServiceMetadataData serviceData) { + ServiceMetadataDefinition serviceMetadataDefinition = new ServiceMetadataDefinition( + (ServiceMetadataDataDefinition) serviceData.getMetadataDataDefinition()); + + Service service = new Service(serviceMetadataDefinition); + + return service; + } + + @Override + public Either getComponent(String id, Class clazz) { + + Either component = getService(id); + if (component.isRight()) { + return Either.right(component.right().value()); + } + return Either.left(clazz.cast(component.left().value())); + } + + @SuppressWarnings("unchecked") + public Either, StorageOperationStatus> getFollowed(String userId, + Set lifecycleStates, Set lastStateStates, boolean inTransaction) { + + return (Either, StorageOperationStatus>) (Either) getFollowedComponent( + userId, lifecycleStates, lastStateStates, inTransaction, titanGenericDao, NodeTypeEnum.Service); + } + + @SuppressWarnings("unchecked") + @Override + public Either getComponent(String id, boolean inTransaction) { + return (Either) getService(id, inTransaction); + } + + // @Override + // public Either getComponent_tx(String id, + // boolean inTransaction) { + // return (Either) getService_tx(id, + // inTransaction); + // } + + @Override + public Either, StorageOperationStatus> getCatalogData(Map propertiesToMatch, + boolean inTransaction) { + return getComponentCatalogData(NodeTypeEnum.Service, propertiesToMatch, Service.class, + ServiceMetadataData.class, inTransaction); + } + + @Override + public Either updateService(Service service, boolean inTransaction) { + Either result = updateComponent(service, inTransaction, titanGenericDao, + Service.class, NodeTypeEnum.Service); + return result; + } + + @SuppressWarnings("unchecked") + @Override + public Either updateComponent(T component, boolean inTransaction) { + return (Either) updateService((Service) component, inTransaction); + } + + @SuppressWarnings("unchecked") + @Override + public Either deleteComponent(String id, boolean inTransaction) { + return (Either) (Either) deleteService(id, + inTransaction); + } + + @Override + protected ComponentMetadataData getMetaDataFromComponent(Component component) { + return getServiceMetaDataFromService((Service) component); + } + + @Override + public Either getLightComponent(String id, boolean inTransaction) { + return getLightComponent(id, NodeTypeEnum.Service, inTransaction); + } + + @Override + public Either, StorageOperationStatus> getFilteredComponents(Map filters, + boolean inTransaction) { + Either, StorageOperationStatus> components = null; + + String categoryName = filters.get(FilterKeyEnum.CATEGORY); + String distributionStatus = filters.get(FilterKeyEnum.DISTRIBUTION_STATUS); + DistributionStatusEnum distEnum = DistributionStatusEnum.findState(distributionStatus); + if (distributionStatus != null && distEnum == null) { + filters.remove(FilterKeyEnum.CATEGORY); + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + + if (categoryName != null) { // primary filter + components = fetchByCategoryOrSubCategoryName(categoryName, NodeTypeEnum.ServiceNewCategory, + GraphEdgeLabels.CATEGORY.getProperty(), NodeTypeEnum.Service, inTransaction, + ServiceMetadataData.class); + if (components.isLeft() && distEnum != null) {// secondary filter + Predicate statusFilter = p -> ((Service) p).getDistributionStatus().equals(distEnum); + return Either + .left(components.left().value().stream().filter(statusFilter).collect(Collectors.toList())); + } + filters.remove(FilterKeyEnum.DISTRIBUTION_STATUS); + return components; + } + components = fetchByDistributionStatus(distEnum.name(), inTransaction); + if (components.isRight()) { // not found == empty list + return Either.left(new ArrayList<>()); + } + return components; + } + + private Either, StorageOperationStatus> fetchByDistributionStatus(String status, + boolean inTransaction) { + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.DISTRIBUTION_STATUS.getProperty(), status); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + return (Either, StorageOperationStatus>) (Either) getServiceListByCriteria( + props, inTransaction); + } + + @SuppressWarnings("unchecked") + @Override + public Either, StorageOperationStatus> getTesterFollowed(String userId, + Set lifecycleStates, boolean inTransaction) { + return (Either, StorageOperationStatus>) (Either) getTesterFollowedComponent( + userId, lifecycleStates, inTransaction, NodeTypeEnum.Service); + } + + public Either updateDestributionStatus(Service service, User user, + DistributionStatusEnum distributionStatus) { + String userId = user.getUserId(); + Either findUser = findUser(userId); + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } + UserData userData = findUser.left().value(); + + Either serviceMetadataDataRequeset = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), service.getUniqueId(), + ServiceMetadataData.class); + if (serviceMetadataDataRequeset.isRight()) { + TitanOperationStatus status = serviceMetadataDataRequeset.right().value(); + log.error("Cannot find service " + service.getUniqueId() + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.NOT_FOUND); + } + ServiceMetadataData serviceMetadataData = serviceMetadataDataRequeset.left().value(); + + StorageOperationStatus result = StorageOperationStatus.OK; + + Either deleteIncomingRelation = deleteLastDistributionModifierRelation( + service); + if (deleteIncomingRelation.isRight() + && deleteIncomingRelation.right().value() != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to delete user from component " + service.getUniqueId() + ". Edge type is " + + GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteIncomingRelation.right().value()); + return Either.right(result); + } + + Either createRelation = titanGenericDao.createRelation(userData, + serviceMetadataData, GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER, null); + log.debug("After associating user " + userData + " to component " + serviceMetadataData.getUniqueId() + + ". Edge type is " + GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER); + if (createRelation.isRight()) { + log.error("Failed to associate user " + userData + " to component " + serviceMetadataData.getUniqueId() + + ". Edge type is " + GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation.right().value()); + return Either.right(result); + } + service.setDistributionStatus(distributionStatus); + Either updateResponse = updateComponent(service, true, titanGenericDao, + Service.class, NodeTypeEnum.Service); + + return updateResponse; + + } + + private Either deleteLastDistributionModifierRelation(Service service) { + GraphRelation lastDistributionStateModifaierRelation = new GraphRelation(); + lastDistributionStateModifaierRelation.setType(GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(NodeTypeEnum.Service, + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), service.getUniqueId()); + lastDistributionStateModifaierRelation.setTo(relationEndPoint); + Either deleteIncomingRelation = titanGenericDao + .deleteIncomingRelation(lastDistributionStateModifaierRelation); + return deleteIncomingRelation; + } + + @Override + public Either, StorageOperationStatus> getCertifiedServicesWithDistStatus( + Map propertiesToMatch, Set distStatus, boolean inTransaction) { + log.debug("Start getCertifiedServicesWithDistStatus."); + Set servicesSet = new HashSet(); + if (distStatus != null && !distStatus.isEmpty()) { + for (DistributionStatusEnum status : distStatus) { + Map props = new HashMap<>(); + props.putAll(propertiesToMatch); + props.put(GraphPropertiesDictionary.DISTRIBUTION_STATUS.getProperty(), status.name()); + Either, StorageOperationStatus> services = retrieveCertifiedServicesWithStatus( + inTransaction, servicesSet, props); + if (services.isRight()) { + return services; + } else { + servicesSet.addAll(services.left().value()); + } + } + return Either.left(servicesSet); + } else { + return retrieveCertifiedServicesWithStatus(inTransaction, servicesSet, propertiesToMatch); + } + } + + private Either, StorageOperationStatus> retrieveCertifiedServicesWithStatus(boolean inTransaction, + Set servicesSet, Map props) { + Either, TitanOperationStatus> criteriaRes = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class); + return retrieveComponentsFromNodes(criteriaRes, inTransaction); + } + + public Either, StorageOperationStatus> getServiceCatalogData(boolean inTransaction) { + + long start = System.currentTimeMillis(); + + try { + /* + * Map propertiesToMatch = new HashMap<>(); + * propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty + * (), LifecycleStateEnum.CERTIFIED.name()); + * Either, TitanOperationStatus> + * lastVersionNodes = getLastVersion(NodeTypeEnum.Service, + * propertiesToMatch, ServiceMetadataData.class); if + * (lastVersionNodes.isRight() && lastVersionNodes.right().value() + * != TitanOperationStatus.NOT_FOUND) { return + * Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus + * (lastVersionNodes.right().value())); } List + * notCertifiedHighest = (lastVersionNodes.isLeft() ? + * lastVersionNodes.left().value() : new + * ArrayList()); + * + * propertiesToMatch.put(GraphPropertiesDictionary. + * IS_HIGHEST_VERSION.getProperty(), true); + * Either, TitanOperationStatus> + * componentsNodes = + * titanGenericDao.getByCriteria(NodeTypeEnum.Service, + * propertiesToMatch, ServiceMetadataData.class); if + * (componentsNodes.isRight() && componentsNodes.right().value() != + * TitanOperationStatus.NOT_FOUND) { return + * Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus + * (componentsNodes.right().value())); } List + * certifiedHighest = (componentsNodes.isLeft() ? + * componentsNodes.left().value() : new + * ArrayList()); + */ + + Either, TitanOperationStatus> listOfHighestComponents = this + .getListOfHighestComponents(NodeTypeEnum.Service, ServiceMetadataData.class); + if (listOfHighestComponents.isRight() + && listOfHighestComponents.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(listOfHighestComponents.right().value())); + } + + List notCertifiedHighest = listOfHighestComponents.left().value(); + + List result = new ArrayList<>(); + + if (notCertifiedHighest != null && false == notCertifiedHighest.isEmpty()) { + + // fetch from cache + long startFetchAllFromCache = System.currentTimeMillis(); + + Map components = notCertifiedHighest.stream() + .collect(Collectors.toMap(p -> p.getMetadataDataDefinition().getUniqueId(), + p -> p.getMetadataDataDefinition().getLastUpdateDate())); + + Either, Set>, ActionStatus> componentsFromCacheForCatalog = this + .getComponentsFromCacheForCatalog(components, ComponentTypeEnum.SERVICE); + if (componentsFromCacheForCatalog.isLeft()) { + ImmutablePair, Set> immutablePair = componentsFromCacheForCatalog.left() + .value(); + List list = immutablePair.getLeft(); + if (list != null) { + for (Component component : list) { + result.add((Service) component); + } + List addedUids = list.stream() + .map(p -> p.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId()) + .collect(Collectors.toList()); + notCertifiedHighest = notCertifiedHighest.stream() + .filter(p -> false == addedUids.contains(p.getMetadataDataDefinition().getUniqueId())) + .collect(Collectors.toList()); + } + } + long endFetchAllFromCache = System.currentTimeMillis(); + log.debug("Fetch all catalog services metadata from cache took {} ms", + (endFetchAllFromCache - startFetchAllFromCache)); + log.debug("The number of services added to catalog from cache is {}", result.size()); + + log.debug("The number of services needed to be fetch as light component is {}", + notCertifiedHighest.size()); + for (ServiceMetadataData data : notCertifiedHighest) { + Either component = getLightComponent( + data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get Service for id = {}, error : {}. Skip service", data.getUniqueId(), + component.right().value()); + } else { + result.add(component.left().value()); + } + } + } + return Either.left(result); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + log.debug("Fetch all catalog services took " + (System.currentTimeMillis() - start) + " ms"); + } + + } + + public Either, StorageOperationStatus> getServiceCatalogDataLatestCertifiedAndNotCertified( + boolean inTransaction) { + Map properties = new HashMap<>(); + + properties.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + List result = new ArrayList<>(); + Either, TitanOperationStatus> lastVersionNodes = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, properties, ServiceMetadataData.class); + + if (lastVersionNodes.isRight() && lastVersionNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(lastVersionNodes.right().value())); + } + + List latestServices; + + if (lastVersionNodes.isLeft()) { + latestServices = lastVersionNodes.left().value(); + } else { + return Either.left(result); + } + + for (ServiceMetadataData data : latestServices) { + Either component = getLightComponent( + data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get Service for id = " + data.getUniqueId() + " error : " + + component.right().value() + " skip resource"); + } else { + result.add(component.left().value()); + } + } + + return Either.left(result); + + } + + private Either, StorageOperationStatus> getServiceListByCriteria(Map props, + boolean inTransaction) { + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Service.getName()); + Either, TitanOperationStatus> byCriteria = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class); + + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List services = new ArrayList(); + List servicesDataList = byCriteria.left().value(); + for (ServiceMetadataData data : servicesDataList) { + Either service = getService(data.getMetadataDataDefinition().getUniqueId(), + inTransaction); + if (service.isLeft()) { + services.add(service.left().value()); + } else { + log.debug("Failed to fetch resource for name = " + data.getMetadataDataDefinition().getName() + + " and id = " + data.getUniqueId()); + } + } + return Either.left(services); + } + + public Either, StorageOperationStatus> getServiceListByUuid(String uuid, boolean inTransaction) { + return getLatestServiceByUuid(uuid, false, inTransaction); + } + + public Either, StorageOperationStatus> getLatestServiceByUuid(String uuid, boolean inTransaction) { + return getLatestServiceByUuid(uuid, true, inTransaction); + } + + private Either, StorageOperationStatus> getLatestServiceByUuid(String uuid, boolean isLatest, + boolean inTransaction) { + Map props = new HashMap(); + + if (isLatest) { + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), isLatest); + } + + props.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + return getServiceListByCriteria(props, inTransaction); + } + + public Either, StorageOperationStatus> getServiceListBySystemName(String systemName, + boolean inTransaction) { + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + return getServiceListByCriteria(props, inTransaction); + } + + public Either getServiceByNameAndVersion(String name, String version, + Map additionalParams, boolean inTransaction) { + return getByNamesAndVersion(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), + ValidationUtils.normaliseComponentName(name), version, additionalParams, inTransaction); + } + + @Override + public Either getServiceByNameAndVersion(String name, String version) { + return getServiceByNameAndVersion(name, version, null, false); + } + + protected Either getByNamesAndVersion(String nameKey, String nameValue, + String version, Map additionalParams, boolean inTransaction) { + Map props = new HashMap(); + props.put(nameKey, nameValue); + props.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Service.getName()); + if (additionalParams != null && !additionalParams.isEmpty()) { + props.putAll(additionalParams); + } + + Either, TitanOperationStatus> byCriteria = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class); + + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List dataList = byCriteria.left().value(); + if (dataList != null && !dataList.isEmpty()) { + if (dataList.size() > 1) { + log.debug("More that one instance of resource for name =" + nameValue + " and version = " + version); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + ServiceMetadataData serviceData = dataList.get(0); + Either service = getService( + serviceData.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (service.isRight()) { + log.debug("Failed to fetch resource for name = " + serviceData.getMetadataDataDefinition().getName() + + " and id = " + serviceData.getMetadataDataDefinition().getUniqueId()); + } + return service; + } + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + protected Either getComponentByNameAndVersion(String name, String version, + Map additionalParams, boolean inTransaction) { + return (Either) getServiceByNameAndVersion(name, version, additionalParams, + inTransaction); + } + + @Override + public Either getServiceBySystemNameAndVersion(String name, String version, + boolean inTransaction) { + return getByNamesAndVersion(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), name, version, null, + inTransaction); + } + + private TitanOperationStatus setServiceAdditionalInformationFromGraph(String uniqueId, Service service) { + + List additionalInformation = new ArrayList<>(); + + Either either = additionalInformationOperation + .getAllAdditionalInformationParameters(NodeTypeEnum.Service, uniqueId, true); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return TitanOperationStatus.OK; + } + return status; + } + + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + additionalInformation.add(additionalInformationDefinition); + + service.setAdditionalInformation(additionalInformation); + + return TitanOperationStatus.OK; + + } + + private TitanOperationStatus setAllVersions(Service service) { + Either, TitanOperationStatus> res = getVersionList(NodeTypeEnum.Service, + service.getVersion(), service, ServiceMetadataData.class); + if (res.isRight()) { + return res.right().value(); + } + service.setAllVersions(res.left().value()); + return TitanOperationStatus.OK; + } + + public Either, StorageOperationStatus> getAdditionalArtifacts(String resourceId, + boolean recursively, boolean inTransaction) { + List artifacts = new ArrayList<>(); + return Either.left(artifacts); + } + + @Override + public boolean isComponentExist(String serviceId) { + return isComponentExist(serviceId, NodeTypeEnum.Service); + } + + // @SuppressWarnings("unchecked") + // @Override + // public Either cloneComponent(T other, + // String version, boolean inTransaction) { + // return (Either) cloneService((Service)other, + // version, inTransaction); + // } + + @SuppressWarnings("unchecked") + @Override + public Either cloneComponent(T other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + return (Either) cloneService((Service) other, version, targetLifecycle, + inTransaction); + } + + @Override + public Either increaseAndGetComponentInstanceCounter(String componentId, + boolean inTransaction) { + return increaseAndGetComponentInstanceCounter(componentId, NodeTypeEnum.Service, inTransaction); + } + + @Override + protected StorageOperationStatus validateCategories(Component currentComponent, Component component, + ComponentMetadataData componentData, NodeTypeEnum type) { + List newcategories = component.getCategories(); + CategoryDefinition newCat = newcategories.get(0); + CategoryDefinition currentCategory = currentComponent.getCategories().get(0); + + StorageOperationStatus status = StorageOperationStatus.OK; + if (newCat != null && newCat.getName() != null && false == newCat.getName().equals(currentCategory.getName())) { + log.debug( + "Going to update the category of the resource from " + currentCategory + " to " + newCat.getName()); + + status = moveCategoryEdge(component, componentData, newCat, type); + log.debug("Going to update the category of the resource from " + currentCategory + " to " + newCat.getName() + + ". status is " + status); + } + return status; + } + + @Override + protected StorageOperationStatus updateDerived(Component component, + Component currentComponent, ComponentMetadataData componentData, Class clazz) { + log.debug("Derived class isn't supported for resource"); + return null; + } + + @Override + public Service getDefaultComponent() { + return new Service(); + } + + @Override + public Either getMetadataComponent(String id, boolean inTransaction) { + return getMetadataComponent(id, NodeTypeEnum.Service, inTransaction); + } + + @Override + Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) { + return convertServiceDataToService((ServiceMetadataData) componentMetadataData); + } + + @Override + public Either validateComponentNameExists(String componentName) { + return validateComponentNameUniqueness(componentName, titanGenericDao, NodeTypeEnum.Service); + } + + @Override + public Either markComponentToDelete(Component componentToDelete, + boolean inTransaction) { + return internalMarkComponentToDelete(componentToDelete, inTransaction); + } + + @Override + public Either isComponentInUse(String componentId) { + return isComponentInUse(componentId, NodeTypeEnum.Service); + } + + @Override + public Either, StorageOperationStatus> getAllComponentsMarkedForDeletion() { + return getAllComponentsMarkedForDeletion(NodeTypeEnum.Service); + } + + @SuppressWarnings("unchecked") + @Override + public Either getComponent(String id, + ComponentParametersView componentParametersView, boolean inTransaction) { + + Either component = getService(id, componentParametersView, inTransaction); + if (component.isRight()) { + return Either.right(component.right().value()); + } + return (Either) component; + } + + public Either updateService(Service service, boolean inTransaction, + ComponentParametersView filterResultView) { + return (Either) updateComponentFilterResult(service, inTransaction, + titanGenericDao, service.getClass(), NodeTypeEnum.Service, filterResultView); + } + + @Override + protected Either updateComponentFilterResult(T component, boolean inTransaction, + ComponentParametersView filterResultView) { + return (Either) updateService((Service) component, inTransaction, filterResultView); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java new file mode 100644 index 0000000000..c4bcf6d907 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java @@ -0,0 +1,244 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.resources.data.ResourceCategoryData; +import org.openecomp.sdc.be.resources.data.ServiceCategoryData; +import org.openecomp.sdc.be.resources.data.TagData; +import org.openecomp.sdc.be.resources.data.UserData; + +public class UniqueIdBuilder { + + private static String DOT = "."; + private static final String HEAT_PARAM_PREFIX = "heat_"; + + public static String buildPropertyUniqueId(String resourceId, String propertyName) { + return resourceId + DOT + propertyName; + } + + public static String buildHeatParameterUniqueId(String resourceId, String propertyName) { + return resourceId + DOT + HEAT_PARAM_PREFIX + propertyName; + } + + public static String buildHeatParameterValueUniqueId(String resourceId, String artifactLabel, String propertyName) { + return resourceId + DOT + artifactLabel + DOT + propertyName; + } + + private static UserData userData = new UserData(); + private static TagData tagData = new TagData(); + private static ResourceCategoryData resCategoryData = new ResourceCategoryData(); + private static ServiceCategoryData serCategoryData = new ServiceCategoryData(); + + private static Map nodeTypeToUniqueKeyMapper = new HashMap(); + + static { + + nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.User, userData.getUniqueIdKey()); + nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.Tag, tagData.getUniqueIdKey()); + nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.ResourceCategory, resCategoryData.getUniqueIdKey()); + nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.ServiceCategory, serCategoryData.getUniqueIdKey()); + } + + /** + * find the unique id key of a node on the graph + * + * @param nodeTypeEnum + * @return + */ + public static String getKeyByNodeType(NodeTypeEnum nodeTypeEnum) { + + String key = nodeTypeToUniqueKeyMapper.get(nodeTypeEnum); + if (key == null) { + key = GraphPropertiesDictionary.UNIQUE_ID.getProperty(); + } + + return key; + } + + public static String buildResourceUniqueId() { + return generateUUID(); + } + + public static String generateUUID() { + UUID uuid = UUID.randomUUID(); + return uuid.toString(); + } + + public static String buildComponentUniqueId() { + return generateUUID(); + } + + public static String buildConstantProductId() { + return generateUUID(); + } + + public static String buildCapabilityTypeUid(String type) { + return type; + } + + public static String buildAttributeUid(String resourceId, String attName) { + return NodeTypeEnum.Attribute.getName() + DOT + resourceId + DOT + attName; + } + + public static String buildRequirementUid(String resourceId, String reqName) { + return resourceId + DOT + reqName; + } + + public static String buildRequirementImplUid(String resourceId, String reqName) { + + return NodeTypeEnum.RequirementImpl.getName() + DOT + resourceId + DOT + reqName; + + } + + public static String buildCapabilityUid(String resourceId, String capabilityName) { + return NodeTypeEnum.Capability.getName() + DOT + resourceId + DOT + capabilityName; + } + + public static String buildCapabilityInstanceUid(String parentId, String capabilityName) { + return NodeTypeEnum.CapabilityInst.getName() + DOT + parentId + DOT + capabilityName; + } + + public static String buildPropertyValueUniqueId(String parentId, String paramName) { + return NodeTypeEnum.PropertyValue.getName() + DOT + parentId + DOT + paramName; + } + + public static String buildArtifactByInterfaceUniqueId(String resourceId, String interfaceName, String operation, + String artifactLabel) { + + return resourceId + DOT + interfaceName + DOT + operation + DOT + artifactLabel; + } + + // public static String + // buildArtifactByInterfaceUniqueIdAndRsrcNameVersion(String + // resourceName,String resourceVersion,String interfaceName,String + // operation,String artifactLabel) { + // String resourceId = UniqueIdBuilder.buildResourceUniqueId(resourceName, + // resourceVersion); + // return resourceId + DOT + interfaceName + DOT +operation + DOT + + // artifactLabel; + // } + public static String buildArtifactByInterfaceUniqueIdAndRsrcId(String resourceId, String interfaceName, + String operation, String artifactLabel) { + return resourceId + DOT + interfaceName + DOT + operation + DOT + artifactLabel; + } + + public static String buildOperationByInterfaceUniqueId(String resourceId, String interfaceName, String operation) { + + return resourceId + DOT + interfaceName + DOT + operation; + } + + public static String buildInterfaceUniqueId(String resourceId, String interfaceName) { + return resourceId + DOT + interfaceName; + } + + public static String buildResourceInstanceUniuqeId(String serviceId, String resourceId, String logicalName) { + + return serviceId + DOT + resourceId + DOT + logicalName; + } + + public static String buildRelationsipInstInstanceUid(String resourceInstUid, String requirement) { + + return generateUUID(); + } + + /* + * TODO Pavel To be removed when new category logic comes in + */ + public static String buildResourceCategoryUid(String categoryName, String subcategoryName, NodeTypeEnum type) { + return type.getName() + DOT + categoryName + DOT + subcategoryName; + } + + /* + * TODO Pavel To be removed when new category logic comes in + */ + public static String buildServiceCategoryUid(String categoryName, NodeTypeEnum type) { + return type.getName() + DOT + categoryName; + } + + // New logic + public static String buildCategoryUid(String categoryName, NodeTypeEnum type) { + return type.getName() + DOT + categoryName; + } + + public static String buildSubCategoryUid(String categoryUid, String subCategoryName) { + return categoryUid + DOT + subCategoryName; + } + + public static String buildGroupingUid(String subCategoryUid, String groupingName) { + return subCategoryUid + DOT + groupingName; + } + + public static String buildResourceInstancePropertyValueUid(String resourceInstanceUniqueId, Integer index) { + return resourceInstanceUniqueId + DOT + "property" + DOT + index; + } + + public static String buildResourceInstanceAttributeValueUid(String resourceInstanceUniqueId, Integer index) { + return resourceInstanceUniqueId + DOT + "attribute" + DOT + index; + } + + public static String buildResourceInstanceInputValueUid(String resourceInstanceUniqueId, Integer index) { + return resourceInstanceUniqueId + DOT + "input" + DOT + index; + } + + public static String buildAdditionalInformationUniqueId(String resourceUniqueId) { + return resourceUniqueId + DOT + "additionalinformation"; + } + + public static String buildHeatParamValueUid(String heatEnvArtifactId, String parameterName) { + return heatEnvArtifactId + DOT + parameterName; + } + + public static String buildDataTypeUid(String name) { + return name + DOT + "datatype"; + } + + public static String buildInvariantUUID() { + return generateUUID(); + } + + public static String buildGroupTypeUid(String type, String version) { + return type + DOT + version + DOT + "grouptype"; + } + + public static String buildPolicyTypeUid(String type, String version) { + return type + DOT + version + DOT + "policytype"; + } + + public static String buildGroupUniqueId(String componentId, String name) { + return componentId + DOT + name + DOT + "group"; + } + + public static String buildGroupPropertyValueUid(String groupUniqueId, Integer index) { + return groupUniqueId + DOT + "property" + DOT + index; + + } + + public static String buildUserFunctionalMenuUid(String userId) { + return userId + DOT + "functionalmenu"; + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java new file mode 100644 index 0000000000..85bb56f39f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java @@ -0,0 +1,501 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +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.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.openecomp.sdc.be.dao.api.ActionStatus; +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.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.FunctionalMenuInfo; +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.UserData; +import org.openecomp.sdc.be.resources.data.UserFunctionalMenuData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.MethodActivationStatusEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@Component("user-operation") +public class UserAdminOperation implements IUserAdminOperation { + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + public UserAdminOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(UserAdminOperation.class.getName()); + + @Override + public Either getInactiveUserData(String id) { + return getUserData(id, false, false); + } + + @Override + public Either getUserData(String id, boolean inTransaction) { + return getUserData(id, true, inTransaction); + } + + private Either getUserData(String id, boolean isActive, boolean inTransaction) { + log.debug("getUserData - start"); + Wrapper> resultWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + try { + validateUserExists(resultWrapper, userWrapper, id); + + if (resultWrapper.isEmpty()) { + validateUserData(resultWrapper, userWrapper.getInnerElement(), id); + + } + if (resultWrapper.isEmpty()) { + if (isActive) { + validateActiveUser(resultWrapper, userWrapper.getInnerElement()); + } else { + validateInActiveUser(resultWrapper, userWrapper.getInnerElement()); + } + } + + if (resultWrapper.isEmpty()) { + Either result = Either.left(convertToUser(userWrapper.getInnerElement())); + resultWrapper.setInnerElement(result); + } + + return resultWrapper.getInnerElement(); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + log.debug("getUserData - end"); + } + } + + private void validateInActiveUser(Wrapper> resultWrapper, UserData userData) { + User user = convertToUser(userData); + if (user.getStatus() == UserStatusEnum.ACTIVE) { + Either result = Either.right(ActionStatus.USER_NOT_FOUND); + resultWrapper.setInnerElement(result); + } + } + + private void validateActiveUser(Wrapper> resultWrapper, UserData userData) { + User user = convertToUser(userData); + if (user.getStatus() == UserStatusEnum.INACTIVE) { + Either result = Either.right(ActionStatus.USER_INACTIVE); + resultWrapper.setInnerElement(result); + } + } + + private void validateUserData(Wrapper> resultWrapper, UserData userData, String id) { + if (userData == null) { + log.debug("Problem get User with userId {}. Reason - either.left().value() = null", id); + Either result = Either.right(ActionStatus.GENERAL_ERROR); + resultWrapper.setInnerElement(result); + } + } + + private void validateUserExists(Wrapper> resultWrapper, Wrapper userWrapper, + String id) { + Either result; + if (id == null) { + log.info("User userId is empty"); + result = Either.right(ActionStatus.MISSING_INFORMATION); + resultWrapper.setInnerElement(result); + return; + } + id = id.toLowerCase(); + Either either = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class); + + if (either.isRight()) { + if (either.right().value() == TitanOperationStatus.NOT_FOUND) { + log.debug("User with userId {} not found", id); + result = Either.right(ActionStatus.USER_NOT_FOUND); + resultWrapper.setInnerElement(result); + } else { + log.debug("Problem get User with userId {}. Reason - {}", id, either.right().value().name()); + result = Either.right(ActionStatus.GENERAL_ERROR); + resultWrapper.setInnerElement(result); + } + } else { + userWrapper.setInnerElement(either.left().value()); + } + } + + @Override + public Either saveUserData(User user) { + + Either result = null; + try { + UserData userData = convertToUserData(user); + result = titanGenericDao.createNode(userData, UserData.class); + if (result.isRight()) { + log.debug("Problem while saving User {}. Reason - {}", userData.toString(), result.right().value().name()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + log.debug("User {} saved successfully", userData.toString()); + return Either.left(convertToUser(result.left().value())); + + } finally { + + if (result == null || result.isRight()) { + log.error("saveUserData - Failed"); + titanGenericDao.rollback(); + } else { + log.debug("saveUserData - end"); + titanGenericDao.commit(); + } + } + } + + @Override + public Either updateUserData(User user) { + Either result = null; + try { + log.debug("updateUserData - start"); + UserData userData = convertToUserData(user); + result = titanGenericDao.updateNode(userData, UserData.class); + if (result.isRight()) { + log.debug("Problem while updating User {}. Reason - {}", userData.toString(), result.right().value().name()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + log.debug("User {} updated successfully", userData.toString()); + return Either.left(convertToUser(result.left().value())); + + } finally { + + if (result == null || result.isRight()) { + log.error("updateUserData - Failed"); + titanGenericDao.rollback(); + } else { + log.debug("updateUserData - end"); + titanGenericDao.commit(); + } + + } + } + + @Override + public Either deActivateUser(User user) { + Either result; + user.setStatus(UserStatusEnum.INACTIVE); + Either status = updateUserData(user); + if (status.isRight()) { + result = Either.right(status.right().value()); + } else { + result = Either.left(user); + } + return result; + } + + @Override + public Either deleteUserData(String id) { + Either result; + Either eitherGet = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class); + if (eitherGet.isRight()) { + log.debug("Problem while retriving user with userId {}", id); + if (eitherGet.right().value() == TitanOperationStatus.NOT_FOUND) { + result = Either.right(ActionStatus.USER_NOT_FOUND); + } else { + result = Either.right(ActionStatus.GENERAL_ERROR); + } + + } else { + result = deleteUserLogic(eitherGet.left().value()); + } + return result; + } + + private Either deleteUserLogic(UserData userData) { + Wrapper> resultWrapper = new Wrapper<>(); + try { + validateUserHasNoConnections(resultWrapper, userData); + + if (resultWrapper.isEmpty()) { + deleteUser(resultWrapper, userData); + } + + } finally { + titanGenericDao.commit(); + } + + return resultWrapper.getInnerElement(); + } + + private void deleteUser(Wrapper> resultWrapper, UserData userData) { + Either eitherDelete = titanGenericDao.deleteNode(userData, UserData.class); + if (eitherDelete.isRight()) { + log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), eitherDelete.right().value().name()); + Either result = Either.right(ActionStatus.GENERAL_ERROR); + resultWrapper.setInnerElement(result); + } else { + log.debug("User {} deleted successfully", userData.toString()); + Either result = Either.left(convertToUser(eitherDelete.left().value())); + resultWrapper.setInnerElement(result); + } + } + + private void validateUserHasNoConnections(Wrapper> resultWrapper, UserData userData) { + if (resultWrapper.isEmpty()) { + + Either, TitanOperationStatus> edgesForNode = titanGenericDao.getEdgesForNode(userData, + Direction.BOTH); + if (edgesForNode.isRight()) { + log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), edgesForNode.right().value().name()); + Either result = Either.right(ActionStatus.GENERAL_ERROR); + resultWrapper.setInnerElement(result); + } else { + List vertexEdges = edgesForNode.left().value(); + if (vertexEdges.size() > 0) { + Either result = Either.right(ActionStatus.USER_HAS_ACTIVE_ELEMENTS); + resultWrapper.setInnerElement(result); + } + } + } + } + + public Either, StorageOperationStatus> getUserPandingTasksList(User user, + Map properties) { + + UserData userData = convertToUserData(user); + + Either vertexUser = titanGenericDao + .getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), user.getUserId()); + if (vertexUser.isRight()) { + log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), vertexUser.right().value().name()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + List pandingTasks = new ArrayList<>(); + Either, TitanOperationStatus> edges = titanGenericDao + .getOutgoingEdgesByCriteria(vertexUser.left().value(), GraphEdgeLabels.STATE, properties); + + if (edges.isRight() || edges.left().value() == null) { + if (edges.right().value() == TitanOperationStatus.NOT_FOUND) { + return Either.left(pandingTasks); + } else { + log.debug("Problem while deleting User {}", userData.toString(), edges.right().value().name()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + + for (Edge edge : edges.left().value()) { + Vertex componentVertex = edge.inVertex(); + VertexProperty property = componentVertex + .property(GraphPropertiesDictionary.IS_DELETED.getProperty()); + if (!property.isPresent()) { + pandingTasks.add(edge); + } else { + Boolean isDeletedValue = (java.lang.Boolean) property.value(); + if (isDeletedValue == null || isDeletedValue == false) { + pandingTasks.add(edge); + } + } + } + + return Either.left(pandingTasks); + } + + @Override + public Either, ActionStatus> getAllUsersWithRole(String role, String status) { + try { + List result = new ArrayList<>(); + Map propertiesToMatch = new HashMap<>(); + if (role != null && !role.trim().isEmpty()) { + propertiesToMatch.put(GraphPropertiesDictionary.ROLE.getProperty(), role); + } + if (status != null && !status.isEmpty()) { + propertiesToMatch.put(GraphPropertiesDictionary.USER_STATUS.getProperty(), status); + } + + Either, TitanOperationStatus> userNodes = titanGenericDao.getByCriteria(NodeTypeEnum.User, + propertiesToMatch, UserData.class); + + titanGenericDao.commit(); + if (userNodes.isRight()) { + // in case of NOT_FOUND from Titan return empty list + if (userNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.left(result); + } else { + log.error("Problem while getting all users with role {}. Reason - {}", role, userNodes.right().value().name()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + } else { + List userDataList = userNodes.left().value(); + if (userDataList != null) { + for (UserData userData : userDataList) { + User user = convertToUser(userData); + result.add(user); + } + return Either.left(result); + } + log.debug("No users were found with role {}", role); + return Either.left(result); + } + } finally { + titanGenericDao.commit(); + } + } + + protected User convertToUser(UserData userData) { + User user = new User(); + user.setUserId(userData.getUserId()); + user.setEmail(userData.getEmail()); + user.setFirstName(userData.getFirstName()); + user.setLastName(userData.getLastName()); + user.setRole(userData.getRole()); + user.setLastLoginTime(userData.getLastLoginTime()); + // Support backward compatibility - user status may not exist in old + // users + Either either = UserStatusEnum.findByName(userData.getStatus()); + user.setStatus(either.isLeft() ? either.left().value() : UserStatusEnum.ACTIVE); + return user; + } + + protected UserData convertToUserData(User user) { + UserData userData = new UserData(); + userData.setUserId(user.getUserId().toLowerCase()); + userData.setEmail(user.getEmail()); + userData.setFirstName(user.getFirstName()); + userData.setLastName(user.getLastName()); + userData.setRole(user.getRole()); + userData.setStatus(user.getStatus().name()); + userData.setLastLoginTime(user.getLastLoginTime()); + return userData; + } + + public Either, ActionStatus> getUserDataWithFunctionalMenu(String userId) { + + Either userData = getUserData(userId, true, true); + + if (userData.isRight()) { + return Either.right(userData.right().value()); + } + User user = userData.left().value(); + Either functionalMenu = getFunctionalMenu(userId); + + FunctionalMenuInfo functionalMenuInfo = new FunctionalMenuInfo(); + if (functionalMenu.isRight()) { + TitanOperationStatus status = functionalMenu.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(ActionStatus.GENERAL_ERROR); + } + } else { + UserFunctionalMenuData userFunctionalMenuData = functionalMenu.left().value(); + functionalMenuInfo.setFunctionalMenu(userFunctionalMenuData.getFunctionalMenu()); + } + + ImmutablePair result = new ImmutablePair(user, + functionalMenuInfo); + + return Either.left(result); + } + + public Either getFunctionalMenu(String userId) { + + Either result; + if (userId == null) { + log.info("User userId is empty"); + result = Either.right(TitanOperationStatus.NOT_FOUND); + return result; + } + userId = userId.toLowerCase(); + String uid = UniqueIdBuilder.buildUserFunctionalMenuUid(userId); + + Either either = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.UserFunctionalMenu), uid, UserFunctionalMenuData.class); + + return either; + } + + public Either createOrUpdateFunctionalMenu(String userId, String newFunctionalMenu) { + + Either functionalMenu = getFunctionalMenu(userId); + + if (functionalMenu.isRight()) { + TitanOperationStatus status = functionalMenu.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + String uid = UniqueIdBuilder.buildUserFunctionalMenuUid(userId); + UserFunctionalMenuData functionalMenuData = new UserFunctionalMenuData(newFunctionalMenu, uid); + + Either createNode = titanGenericDao + .createNode(functionalMenuData, UserFunctionalMenuData.class); + + if (createNode.isRight()) { + return Either.right(createNode.right().value()); + } else { + return Either.left(convert(createNode.left().value())); + } + + } else { + return Either.right(status); + } + + } else { + UserFunctionalMenuData userFunctionalMenuData = functionalMenu.left().value(); + userFunctionalMenuData.setFunctionalMenu(newFunctionalMenu); + Either updateNode = titanGenericDao + .updateNode(userFunctionalMenuData, UserFunctionalMenuData.class); + + if (updateNode.isRight()) { + return Either.right(updateNode.right().value()); + } else { + return Either.left(convert(updateNode.left().value())); + } + } + + } + + private FunctionalMenuInfo convert(UserFunctionalMenuData functionalMenuData) { + + if (functionalMenuData == null) { + return null; + } + + FunctionalMenuInfo functionalMenuInfo = new FunctionalMenuInfo(); + functionalMenuInfo.setFunctionalMenu(functionalMenuData.getFunctionalMenu()); + + return functionalMenuInfo; + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java new file mode 100644 index 0000000000..fd6563ac4f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.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.model.operations.utils; + +import org.openecomp.sdc.be.model.Component; +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.operations.api.IComponentOperation; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class ComponentValidationUtils { + + private static Logger log = LoggerFactory.getLogger(ComponentValidationUtils.class.getName()); + + public static boolean canWorkOnResource(Resource resource, String userId) { + // verify resource is checked-out + if (resource.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) { + log.debug("resource is not checked-out"); + return false; + } + // verify resource is not deleted + if ((resource.getIsDeleted() != null) && (resource.getIsDeleted() == true)) { + log.debug("resource is marked as delete"); + return false; + } + // verify resource last update user is the current user + if (!userId.equals(resource.getLastUpdaterUserId())) { + log.debug("resource last update is not {}", userId); + return false; + } + return true; + } + + public static boolean canWorkOnResource(String resourceId, IResourceOperation resourceOperation, + String userId) { + Either getResourceResult = resourceOperation.getLightComponent(resourceId, + false); + + if (getResourceResult.isRight()) { + log.debug("Failed to retrive resource, resource id {}", resourceId); + return false; + } + Resource resource = getResourceResult.left().value(); + + return canWorkOnResource(resource, userId); + + } + + public static boolean canWorkOnService(String serviceId, IServiceOperation serviceOperation, String userId) { + Either getResourceResult = serviceOperation.getLightComponent(serviceId, + false); + + if (getResourceResult.isRight()) { + log.debug("Failed to retrieve service, service id {}", serviceId); + return false; + } + Service service = getResourceResult.left().value(); + + return canWorkOnComponent(service, userId); + + } + + public static boolean canWorkOnComponent(String componentId, IComponentOperation componentOperation, + String userId) { + Either getResourceResult = componentOperation.getLightComponent(componentId, + false); + + if (getResourceResult.isRight()) { + log.debug("Failed to retrieve component, component id {}", componentId); + return false; + } + Component service = getResourceResult.left().value(); + + return canWorkOnComponent(service, userId); + } + + public static boolean canWorkOnComponent(Component component, String userId) { + // verify resource is checked-out + if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) { + log.debug("resource is not checked-out"); + return false; + } + + // verify userId is not null + if (userId == null) { + log.debug("current user userId is null"); + return false; + } + + // verify resource last update user is the current user + if (!userId.equals(component.getLastUpdaterUserId())) { + log.debug("resource last updater userId is not {}", userId); + return false; + } + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java new file mode 100644 index 0000000000..1d78252de2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.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.model.operations.utils; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +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.Property; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GraphDeleteUtil { + + private static Logger log = LoggerFactory.getLogger(GraphDeleteUtil.class.getName()); + + public TitanOperationStatus deleteChildrenNodes(Vertex rootVertex, GraphEdgeLabels edgeType) { + + // Iterable edgesCreatorIterable = + // rootVertex.getEdges(Direction.OUT, + // edgeType.name()); + Iterator edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty()); + + while (edgesCreatorIterator.hasNext()) { + Edge edge = edgesCreatorIterator.next(); + Vertex incomingVertex = edge.inVertex(); + Iterator outEdges = incomingVertex.edges(Direction.OUT); + + if (outEdges.hasNext()) { + return TitanOperationStatus.CANNOT_DELETE_NON_LEAF_NODE; + } else { + Map properties = null; + if (log.isDebugEnabled()) { + properties = getProperties(incomingVertex); + log.debug("Going to delete vertex {}", properties); + } + incomingVertex.remove(); + if (log.isDebugEnabled()) { + log.debug("After deleting vertex {}", properties); + } + } + + } + + // + // if (edgesCreatorIterable != null) { + // for (Edge edge : edgesCreatorIterable) { + // + // Vertex incomingVertex = edge.getVertex(Direction.IN); + // Iterable outEdges = incomingVertex.getEdges(Direction.OUT); + // if (outEdges != null) { + // if (outEdges.iterator().hasNext()) { + // return TitanOperationStatus.CANNOT_DELETE_NON_LEAF_NODE; + // } else { + // Map properties = null; + // if (log.isDebugEnabled()) { + // properties = ElementHelper.getProperties(incomingVertex); + // log.debug("Going to delete vertex {}", properties); + // } + // incomingVertex.remove(); + // if (log.isDebugEnabled()) { + // log.debug("After deleting vertex {}", properties); + // } + // } + // } + // + // } + // } + + return TitanOperationStatus.OK; + + } + + public Map getProperties(Element element) { + + Map result = null; + + if (element.keys() != null && element.keys().size() > 0) { + Map propertyMap = ElementHelper.propertyMap(element, + element.keys().toArray(new String[element.keys().size()])); + result = new HashMap(); + + for (Entry entry : propertyMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue().value(); + + result.put(key, value); + } + } + return result; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java new file mode 100644 index 0000000000..2bbb84dd20 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.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.be.model.tosca; + +import org.openecomp.sdc.be.model.tosca.converters.BooleanConverter; +import org.openecomp.sdc.be.model.tosca.converters.DefaultConverter; +import org.openecomp.sdc.be.model.tosca.converters.FloatConverter; +import org.openecomp.sdc.be.model.tosca.converters.IntegerConverter; +import org.openecomp.sdc.be.model.tosca.converters.JsonConverter; +import org.openecomp.sdc.be.model.tosca.converters.ListConverter; +import org.openecomp.sdc.be.model.tosca.converters.MapConverter; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.StringConvertor; +import org.openecomp.sdc.be.model.tosca.converters.ToscaBooleanConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaFloatConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaJsonValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaListValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaStringConvertor; +import org.openecomp.sdc.be.model.tosca.converters.ToscaValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaValueDefaultConverter; +import org.openecomp.sdc.be.model.tosca.validators.BooleanValidator; +import org.openecomp.sdc.be.model.tosca.validators.FloatValidator; +import org.openecomp.sdc.be.model.tosca.validators.IntegerValidator; +import org.openecomp.sdc.be.model.tosca.validators.JsonValidator; +import org.openecomp.sdc.be.model.tosca.validators.KeyValidator; +import org.openecomp.sdc.be.model.tosca.validators.ListValidator; +import org.openecomp.sdc.be.model.tosca.validators.MapValidator; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; +import org.openecomp.sdc.be.model.tosca.validators.StringValidator; + +/** + * The primitive type that TOSCA YAML supports. + * + * @author esofer + */ +public enum ToscaPropertyType { + + Root("tosca.datatypes.Root", null, null, null, true), + + STRING("string", StringValidator.getInstance(), StringConvertor.getInstance(), ToscaStringConvertor.getInstance()), + + BOOLEAN("boolean", BooleanValidator.getInstance(), ToscaBooleanConverter.getInstance(), + BooleanConverter.getInstance()), + + FLOAT("float", FloatValidator.getInstance(), ToscaFloatConverter.getInstance(), FloatConverter.getInstance()), + + INTEGER("integer", IntegerValidator.getInstance(), DefaultConverter.getInstance(), IntegerConverter.getInstance()), + + SCALAR_UNIT_SIZE("scalar-unit.size", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + SCALAR_UNIT_TIME("scalar-unit.time", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + SCALAR_UNIT_FREQUENCY("scalar-unit.frequency", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + RANGE("range", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + TIMESTAMP("timestamp", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + MAP("map", MapValidator.getInstance(), MapConverter.getInstance(), ToscaMapValueConverter.getInstance()), + + LIST("list", ListValidator.getInstance(), ListConverter.getInstance(), ToscaListValueConverter.getInstance()), + + VERSION("version", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + KEY("key", KeyValidator.getInstance(), StringConvertor.getInstance(), ToscaValueDefaultConverter.getInstance()), + + JSON("json", JsonValidator.getInstance(), JsonConverter.getInstance(), ToscaJsonValueConverter.getInstance()); + + // CREDENTIAL("tosca.datatypes.Credential", StringValidator.getInstance(), + // DefaultConverter.getInstance()); + + private String type; + private PropertyTypeValidator validator; + private PropertyValueConverter converter; + private ToscaValueConverter valueConverter; + private boolean isAbstract = false; + + ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, + ToscaValueConverter valueConverter) { + this.type = type; + this.validator = validator; + this.converter = converter; + this.valueConverter = valueConverter; + } + + ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, + ToscaValueConverter valueConverter, boolean isAbstract) { + this(type, validator, converter, valueConverter); + this.isAbstract = isAbstract; + } + + // private static final Pattern TIMESTAMP_REGEX = Pattern + // .compile("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?([Tt]|[ + // \\t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](\\.[0-9]*)?(([ \\t]*)Z|([ + // \\t]*)[-+][0-9][0-9]?(:[0-9][0-9])?)?"); + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public PropertyTypeValidator getValidator() { + return validator; + } + + public void setValidator(PropertyTypeValidator validator) { + this.validator = validator; + } + + public PropertyValueConverter getConverter() { + return converter; + } + + public void setConverter(PropertyValueConverter converter) { + this.converter = converter; + } + + public boolean isAbstract() { + return isAbstract; + } + + public void setAbstract(boolean isAbstract) { + this.isAbstract = isAbstract; + } + + public ToscaValueConverter getValueConverter() { + return valueConverter; + } + + public void setValueConverter(ToscaValueConverter valueConverter) { + this.valueConverter = valueConverter; + } + + public static ToscaPropertyType isValidType(String typeName) { + if (typeName == null) { + return null; + } + + for (ToscaPropertyType type : ToscaPropertyType.values()) { + if (type.getType().equals(typeName)) { + return type; + } + } + return null; + } + + public static boolean isScalarType(String dataTypeName) { + + ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName); + + return isPrimitiveToscaType != null && isPrimitiveToscaType.isAbstract() == false; + + } + + public static ToscaPropertyType getTypeIfScalar(String dataTypeName) { + + ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName); + + if (isPrimitiveToscaType != null && isPrimitiveToscaType.isAbstract() == false) { + return isPrimitiveToscaType; + } else { + return null; + } + + } + + @Override + public String toString() { + return name().toLowerCase(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java new file mode 100644 index 0000000000..88642f8240 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java @@ -0,0 +1,120 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca; + +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Locale; + +/** + * The primitive type that TOSCA YAML supports. + * + * @author mkv + */ +public enum ToscaType { + STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP, VERSION; + + // private static final Pattern TIMESTAMP_REGEX = Pattern + // .compile("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?([Tt]|[ + // \\t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](\\.[0-9]*)?(([ \\t]*)Z|([ + // \\t]*)[-+][0-9][0-9]?(:[0-9][0-9])?)?"); + + public static ToscaType fromYamlTypeName(String typeName) { + if (typeName == null) { + return null; + } + try { + return ToscaType.valueOf(typeName.toUpperCase()); + } catch (IllegalArgumentException e) { + return null; + } + } + + public boolean isValidValue(String value) { + switch (this) { + case BOOLEAN: + return value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false"); + case FLOAT: + return isFloat(value); + case INTEGER: + return isInteger(value); + case STRING: + return true; + case TIMESTAMP: + try { + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).parse(value); + return true; + } catch (ParseException e) { + return false; + } + case VERSION: + return VersionUtil.isValid(value); + default: + return false; + } + } + + private boolean isFloat(String value) { + try { + Float.valueOf(value); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + private boolean isInteger(String value) { + try { + Long.valueOf(value); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public Object convert(String value) { + switch (this) { + case STRING: + return value; + case BOOLEAN: + return Boolean.valueOf(value); + case FLOAT: + return Double.valueOf(value); + case INTEGER: + return Long.valueOf(value); + case TIMESTAMP: + try { + return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Value must be a valid timestamp", e); + } + case VERSION: + return VersionUtil.parseVersion(value); + default: + return null; + } + } + + @Override + public String toString() { + return name().toLowerCase(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java new file mode 100644 index 0000000000..91d806edd9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.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.model.tosca; + +import java.util.regex.Pattern; + +import org.openecomp.sdc.be.model.tosca.version.ApplicationVersionException; +import org.openecomp.sdc.be.model.tosca.version.Version; + +public final class VersionUtil { + + /** Utility class should not have public constructor. */ + private VersionUtil() { + } + + /** + * The version must begin with a bloc of numbers, and then it can have one + * or more bloc of numbers separated by '.' and then it can have alpha + * numeric bloc separated by '.' or '-' + */ + public static final Pattern VERSION_PATTERN = Pattern.compile("\\d+(?:\\.\\d+)*(?:[\\.-]\\p{Alnum}+)*"); + private static final String SNAPSHOT_IDENTIFIER = "SNAPSHOT"; + + /** + * Check if a version is a SNAPSHOT (development) version. + * + * @param version + * The actual version string. + * @return True if the version is a SNAPSHOT version, false if not (RELEASE + * version). + */ + public static boolean isSnapshot(String version) { + return version.toUpperCase().contains(SNAPSHOT_IDENTIFIER); + } + + /** + * Check if a version is valid + * + * @param version + * version string to parse + * @return true if it's following the defined version pattern + */ + public static boolean isValid(String version) { + return VERSION_PATTERN.matcher(version).matches(); + } + + /** + * Parse the version's text to produce a comparable version object + * + * @param version + * version text to parse + * @return a comparable version object + * @throws ApplicationVersionException + * if the version text is not following the defined version + * pattern + */ + public static Version parseVersion(String version) { + if (!isValid(version)) { + throw new ApplicationVersionException( + "This version is not valid [" + version + "] as it does not match [" + VERSION_PATTERN + "]"); + } else { + return new Version(version); + } + } + + /** + * Compare 2 versions + * + * @param versionLeft + * @param versionRight + * @return + */ + public static int compare(String versionLeft, String versionRight) { + return parseVersion(versionLeft).compareTo(parseVersion(versionRight)); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java new file mode 100644 index 0000000000..7b46692253 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.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.model.tosca.constraints; + +import java.io.Serializable; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +@SuppressWarnings("rawtypes") +public abstract class AbstractComparablePropertyConstraint extends AbstractPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 2002627754053326321L; + + private Comparable comparable; + + protected Comparable getComparable() { + return comparable; + } + + protected void initialize(String rawTextValue, ToscaType propertyType) + throws ConstraintValueDoNotMatchPropertyTypeException { + // Perform verification that the property type is supported for + // comparison + ConstraintUtil.checkComparableType(propertyType); + // Check if the text value is valid for the property type + if (propertyType.isValidValue(rawTextValue)) { + // Convert the raw text value to a comparable value + comparable = ConstraintUtil.convertToComparable(propertyType, rawTextValue); + } else { + // Invalid value throw exception + throw new ConstraintValueDoNotMatchPropertyTypeException( + "The value [" + rawTextValue + "] is not valid for the type [" + propertyType + "]"); + } + } + + protected abstract void doValidate(Object propertyValue) throws ConstraintViolationException; + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + throw new ConstraintViolationException("Value to check is null"); + } + if (!(comparable.getClass().isAssignableFrom(propertyValue.getClass()))) { + throw new ConstraintViolationException("Value to check is not comparable to reference type, value type [" + + propertyValue.getClass() + "], reference type [" + comparable.getClass() + "]"); + } + doValidate(propertyValue); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java new file mode 100644 index 0000000000..950a7fa9b9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.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.model.tosca.constraints; + +import java.io.Serializable; + +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; +import org.openecomp.sdc.be.model.tosca.version.ApplicationVersionException; + +public abstract class AbstractPropertyConstraint implements PropertyConstraint, Serializable { + + /** + * + */ + private static final long serialVersionUID = 4459522275459723374L; + + @Override + public void validate(ToscaType toscaType, String propertyTextValue) throws ConstraintViolationException { + try { + validate(toscaType.convert(propertyTextValue)); + } catch (IllegalArgumentException | ApplicationVersionException e) { + throw new ConstraintViolationException( + "String value [" + propertyTextValue + "] is not valid for type [" + toscaType + "]", e); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java new file mode 100644 index 0000000000..142caa2017 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.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.model.tosca.constraints; + +import java.io.Serializable; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public abstract class AbstractStringPropertyConstraint extends AbstractPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6857605164938136232L; + + protected abstract void doValidate(String propertyValue) throws ConstraintViolationException; + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + throw new ConstraintViolationException("Value to validate is null"); + } + if (!(propertyValue instanceof String)) { + throw new ConstraintViolationException("This constraint can only be applied on String value"); + } + doValidate((String) propertyValue); + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + ConstraintUtil.checkStringType(propertyType); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java new file mode 100644 index 0000000000..5f19d15293 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.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.model.tosca.constraints; + +import java.util.Arrays; +import java.util.List; + +public enum ConstraintType { + + IN_RANGE("inRange"), + + GREATER_THAN("greaterThan", "greater_than"), + + GREATER_OR_EQUAL("greaterOrEqual", "greater_or_equal"), + + LESS_OR_EQUAL("lessOrEqual", "less_or_equal"), + + MIN_LENGTH("minLength", "min_length"), + + VALID_VALUES("validValues", "valid_values"), + + LESS_THAN("lessThan", "less_than"); + + List types; + + private ConstraintType(String... types) { + this.types = Arrays.asList(types); + } + + public List getTypes() { + return types; + } + + public static ConstraintType getByType(String type) { + for (ConstraintType inst : ConstraintType.values()) { + if (inst.getTypes().contains(type)) { + return inst; + } + } + return null; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java new file mode 100644 index 0000000000..79ac5caf25 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.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.be.model.tosca.constraints; + +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; + +/** + * Utility class to validate constraints types. + */ +public final class ConstraintUtil { + + private ConstraintUtil() { + } + + /** + * Validates that the {@link ToscaType} specified is a + * {@link ToscaType#STRING}. + * + * @param propertyType + * The property tosca type. + * @throws ConstraintValueDoNotMatchPropertyTypeException + * In case the type is not {@link ToscaType#STRING}. + */ + public static void checkStringType(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + if (!ToscaType.STRING.equals(propertyType)) { + throw new ConstraintValueDoNotMatchPropertyTypeException( + "Invalid property type <" + propertyType.toString() + ">"); + } + } + + /** + * Verify that the given tosca type is supported for comparison + * + * @param propertyType + * the tosca type to check + * @throws ConstraintValueDoNotMatchPropertyTypeException + * if the property type cannot be compared + */ + public static void checkComparableType(ToscaType propertyType) + throws ConstraintValueDoNotMatchPropertyTypeException { + // The validity of the value is already assured by us with our + // ToscaType.convert() method + // here we just want to check that the constraint is not used on + // unsupported type as boolean + switch (propertyType) { + case FLOAT: + case INTEGER: + case TIMESTAMP: + case VERSION: + break; + case STRING: + case BOOLEAN: + throw new ConstraintValueDoNotMatchPropertyTypeException( + "Constraint is invalid for property type <" + propertyType.toString() + ">"); + default: + throw new ConstraintValueDoNotMatchPropertyTypeException( + "Invalid property type <" + propertyType.toString() + ">"); + } + } + + /** + * Convert a string value following its type throw exception if it cannot be + * converted to a comparable + * + * @param propertyType + * the type of the property + * @param value + * the value to convert + * @return the converted comparable + * @throws ConstraintValueDoNotMatchPropertyTypeException + * if the converted value is not a comparable + */ + @SuppressWarnings("rawtypes") + public static Comparable convertToComparable(ToscaType propertyType, String value) + throws ConstraintValueDoNotMatchPropertyTypeException { + Object comparableObj = propertyType.convert(value); + if (!(comparableObj instanceof Comparable)) { + throw new IllegalArgumentException( + "Try to convert a value of a type which is not comparable [" + propertyType + "] to Comparable"); + } else { + return (Comparable) comparableObj; + } + } + + public static class ConstraintInformation { + public ConstraintInformation(String name, Object reference, String value, String type) { + + this.name = name; + this.reference = reference; + this.value = value; + this.type = type; + + } + + private String name; + private Object reference; + private String value; + private String type; + } + + public static ConstraintInformation getConstraintInformation(Object constraint) throws IntrospectionException { + PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(constraint.getClass()) + .getPropertyDescriptors(); + PropertyDescriptor firstDescriptor = null; + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + if (propertyDescriptor.getReadMethod() != null && propertyDescriptor.getWriteMethod() != null) { + firstDescriptor = propertyDescriptor; + break; + } + } + if (firstDescriptor == null) { + throw new IntrospectionException("Cannot find constraint name"); + } + try { + return new ConstraintInformation(firstDescriptor.getName(), + firstDescriptor.getReadMethod().invoke(constraint), null, null); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new IntrospectionException("Cannot retrieve constraint reference " + e.getMessage()); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java new file mode 100644 index 0000000000..530dcb0cc6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.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.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import com.fasterxml.jackson.annotation.JsonIgnore; + +public class EqualConstraint extends AbstractPropertyConstraint implements Serializable { + /** + * + */ + private static final long serialVersionUID = -1596093341744641483L; + + @NotNull + private String equal; + + // @JsonIgnore + private Object typed; + + public EqualConstraint(String equal) { + super(); + this.equal = equal; + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + if (propertyType.isValidValue(equal)) { + typed = propertyType.convert(equal); + } else { + throw new ConstraintValueDoNotMatchPropertyTypeException("equal constraint has invalid value <" + equal + + "> property type is <" + propertyType.toString() + ">"); + } + } + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + if (typed != null) { + fail(null); + } + } else if (typed == null) { + fail(propertyValue); + } else if (!typed.equals(propertyValue)) { + fail(propertyValue); + } + } + + private void fail(Object propertyValue) throws ConstraintViolationException { + throw new ConstraintViolationException("Equal constraint violation, the reference is <" + equal + + "> but the value to compare is <" + propertyValue + ">"); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java new file mode 100644 index 0000000000..4f2c3ad9ca --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.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.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class GreaterOrEqualConstraint extends AbstractComparablePropertyConstraint implements Serializable { + /** + * + */ + private static final long serialVersionUID = -5937851077034490609L; + + @NotNull + private String greaterOrEqual; + + public GreaterOrEqualConstraint(String greaterOrEqual) { + super(); + this.greaterOrEqual = greaterOrEqual; + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + initialize(greaterOrEqual, propertyType); + } + + @Override + protected void doValidate(Object propertyValue) throws ConstraintViolationException { + if (getComparable().compareTo(propertyValue) > 0) { + throw new ConstraintViolationException(propertyValue + " <= " + greaterOrEqual); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java new file mode 100644 index 0000000000..aea2a201ab --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.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.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class GreaterThanConstraint extends AbstractComparablePropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 405723215512121896L; + + public GreaterThanConstraint(String greaterThan) { + super(); + this.greaterThan = greaterThan; + } + + @NotNull + private String greaterThan; + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + initialize(greaterThan, propertyType); + } + + @Override + protected void doValidate(Object propertyValue) throws ConstraintViolationException { + if (getComparable().compareTo(propertyValue) >= 0) { + throw new ConstraintViolationException(propertyValue + " < " + greaterThan); + } + } + + public String getGreaterThan() { + return greaterThan; + } + + public void setGreaterThan(String greaterThan) { + this.greaterThan = greaterThan; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java new file mode 100644 index 0000000000..e8821c2c21 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.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.model.tosca.constraints; + +import java.io.Serializable; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.Lists; + +public class InRangeConstraint extends AbstractPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -8038401707152824493L; + + private List inRange; + + private Comparable min; + private Comparable max; + + public InRangeConstraint(List inRange) { + super(); + this.inRange = inRange; + } + + public InRangeConstraint() { + super(); + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + // Perform verification that the property type is supported for + // comparison + ConstraintUtil.checkComparableType(propertyType); + if (inRange == null || inRange.size() != 2) { + throw new ConstraintValueDoNotMatchPropertyTypeException("In range constraint must have two elements."); + } + String minRawText = inRange.get(0); + String maxRawText = inRange.get(1); + if (!propertyType.isValidValue(minRawText)) { + throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid min value for in range constraint [" + + minRawText + "] as it does not follow the property type [" + propertyType + "]"); + } + if (!propertyType.isValidValue(maxRawText)) { + throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid max value for in range constraint [" + + maxRawText + "] as it does not follow the property type [" + propertyType + "]"); + } + min = ConstraintUtil.convertToComparable(propertyType, minRawText); + max = ConstraintUtil.convertToComparable(propertyType, maxRawText); + } + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + throw new ConstraintViolationException("Value to check is null"); + } + if (!(min.getClass().isAssignableFrom(propertyValue.getClass()))) { + throw new ConstraintViolationException("Value to check is not comparable to range type, value type [" + + propertyValue.getClass() + "], range type [" + min.getClass() + "]"); + } + if (min.compareTo(propertyValue) > 0 || max.compareTo(propertyValue) < 0) { + throw new ConstraintViolationException("The value [" + propertyValue + "] is out of range " + inRange); + } + } + + // @JsonProperty + @NotNull + public String getRangeMinValue() { + if (inRange != null) { + return inRange.get(0); + } else { + return null; + } + } + + // @JsonProperty + public void setRangeMinValue(String minValue) { + if (inRange == null) { + inRange = Lists.newArrayList(minValue, ""); + } else { + inRange.set(0, minValue); + } + } + + // @JsonProperty + @NotNull + public String getRangeMaxValue() { + if (inRange != null) { + return inRange.get(1); + } else { + return null; + } + } + + // @JsonProperty + public void setRangeMaxValue(String maxValue) { + if (inRange == null) { + inRange = Lists.newArrayList("", maxValue); + } else { + inRange.set(1, maxValue); + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java new file mode 100644 index 0000000000..2ba0071f2f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.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.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class LengthConstraint extends AbstractStringPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6249912030281791233L; + + @NotNull + private Integer length; + + @Override + protected void doValidate(String propertyValue) throws ConstraintViolationException { + if (propertyValue.length() != length) { + throw new ConstraintViolationException("The length of the value is not equals to [" + length + "]"); + } + } + + public Integer getLength() { + return length; + } + + public void setLength(Integer length) { + this.length = length; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java new file mode 100644 index 0000000000..1491fe327d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import alien4cloud.json.deserializer.TextDeserializer; +//import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +public class LessOrEqualConstraint extends AbstractComparablePropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -4907864317687138678L; + + // @JsonDeserialize(using = TextDeserializer.class) + @NotNull + private String lessOrEqual; + + public LessOrEqualConstraint(String lessOrEqual) { + super(); + this.lessOrEqual = lessOrEqual; + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + initialize(lessOrEqual, propertyType); + } + + @Override + protected void doValidate(Object propertyValue) throws ConstraintViolationException { + if (getComparable().compareTo(propertyValue) < 0) { + throw new ConstraintViolationException(propertyValue + " >= " + lessOrEqual); + } + } + + public String getLessOrEqual() { + return lessOrEqual; + } + + public void setLessOrEqual(String lessOrEqual) { + this.lessOrEqual = lessOrEqual; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java new file mode 100644 index 0000000000..2fc43febbf --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.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.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class LessThanConstraint extends AbstractComparablePropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 2267623014703859501L; + + @NotNull + private String lessThan; + + public LessThanConstraint(String lessThan) { + super(); + this.lessThan = lessThan; + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + initialize(lessThan, propertyType); + } + + @Override + protected void doValidate(Object propertyValue) throws ConstraintViolationException { + if (getComparable().compareTo(propertyValue) <= 0) { + throw new ConstraintViolationException(propertyValue + " > " + lessThan); + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java new file mode 100644 index 0000000000..b6a80afced --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.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.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class MaxLengthConstraint extends AbstractStringPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6377603705670201256L; + + @NotNull + private Integer maxLength; + + public MaxLengthConstraint(Integer maxLength) { + this.maxLength = maxLength; + } + + public MaxLengthConstraint() { + super(); + } + + @Override + protected void doValidate(String propertyValue) throws ConstraintViolationException { + if (propertyValue.length() > maxLength) { + throw new ConstraintViolationException("The length of the value is greater than [" + maxLength + "]"); + } + } + + public Integer getMaxLength() { + return maxLength; + } + + public void setMaxLength(Integer maxLength) { + this.maxLength = maxLength; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java new file mode 100644 index 0000000000..f92e5fbb2c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.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.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class MinLengthConstraint extends AbstractStringPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 32422424680811240L; + + @NotNull + private Integer minLength; + + public MinLengthConstraint(Integer minLength) { + this.minLength = minLength; + } + + public MinLengthConstraint() { + super(); + } + + @Override + protected void doValidate(String propertyValue) throws ConstraintViolationException { + if (propertyValue.length() < minLength) { + throw new ConstraintViolationException("The length of the value is less than [" + minLength + "]"); + } + } + + public Integer getMinLength() { + return minLength; + } + + public void setMinLength(Integer minLength) { + this.minLength = minLength; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java new file mode 100644 index 0000000000..c85c1601e4 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.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.be.model.tosca.constraints; + +import java.io.Serializable; +import java.util.regex.Pattern; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import com.fasterxml.jackson.annotation.JsonIgnore; + +public class PatternConstraint extends AbstractStringPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 8708185294968697107L; + + @NotNull + private String pattern; + + // @JsonIgnore + private Pattern compiledPattern; + + public void setPattern(String pattern) { + this.pattern = pattern; + this.compiledPattern = Pattern.compile(this.pattern); + } + + @Override + protected void doValidate(String propertyValue) throws ConstraintViolationException { + if (!compiledPattern.matcher(propertyValue).matches()) { + throw new ConstraintViolationException("The value do not match pattern " + pattern); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java new file mode 100644 index 0000000000..738f5150e3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.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.model.tosca.constraints; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import com.fasterxml.jackson.annotation.JsonIgnore; +import com.google.common.collect.Sets; + +public class ValidValuesConstraint extends AbstractPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 5906087180079892853L; + + @NotNull + private List validValues; + // @JsonIgnore + private Set validValuesTyped; + + public ValidValuesConstraint(List validValues) { + super(); + this.validValues = validValues; + } + + public ValidValuesConstraint() { + super(); + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + validValuesTyped = Sets.newHashSet(); + if (validValues == null) { + throw new ConstraintValueDoNotMatchPropertyTypeException( + "validValues constraint has invalid value <> property type is <" + propertyType.toString() + ">"); + } + for (String value : validValues) { + if (!propertyType.isValidValue(value)) { + throw new ConstraintValueDoNotMatchPropertyTypeException("validValues constraint has invalid value <" + + value + "> property type is <" + propertyType.toString() + ">"); + } else { + validValuesTyped.add(propertyType.convert(value)); + } + } + } + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + throw new ConstraintViolationException("Value to validate is null"); + } + if (!validValuesTyped.contains(propertyValue)) { + throw new ConstraintViolationException("The value is not in the list of valid values"); + } + } + + public List getValidValues() { + return validValues; + } + + public void setValidValues(List validValues) { + this.validValues = validValues; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java new file mode 100644 index 0000000000..3fd165f41e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.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.model.tosca.constraints.exception; + +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil.ConstraintInformation; + +/** + * All functional error related to constraint processing must go here + * + * @author mkv + * + */ +public class ConstraintFunctionalException extends FunctionalException { + + private static final long serialVersionUID = 1L; + + protected ConstraintInformation constraintInformation; + + public ConstraintFunctionalException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintFunctionalException(String message) { + super(message); + } + + public ConstraintFunctionalException(String message, Throwable cause, ConstraintInformation constraintInformation) { + super(message, cause); + this.constraintInformation = constraintInformation; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java new file mode 100644 index 0000000000..2416405de4 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.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.model.tosca.constraints.exception; + +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil.ConstraintInformation; + +/** + * Exception to be thrown when a required property is not provided + * + * @author mourouvi + * + */ +public class ConstraintRequiredParameterException extends ConstraintFunctionalException { + + private static final long serialVersionUID = 1L; + + public ConstraintRequiredParameterException(String message) { + super(message); + } + + public ConstraintRequiredParameterException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintRequiredParameterException(String message, Throwable cause, + ConstraintInformation constraintInformation) { + super(message, cause); + this.constraintInformation = constraintInformation; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java new file mode 100644 index 0000000000..3816ac61dd --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.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.be.model.tosca.constraints.exception; + +/** + * Base class for all constraint related exceptions + * + * @author esofer + * + */ +public class ConstraintTechnicalException extends Exception { + + private static final long serialVersionUID = 5829360730980521567L; + + public ConstraintTechnicalException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintTechnicalException(String message) { + super(message); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java new file mode 100644 index 0000000000..6ba0d9b864 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.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.model.tosca.constraints.exception; + +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil.ConstraintInformation; + +/** + * Exception to be thrown when a constraint definition is invalid because the + * specified value doesn't match the property type. + * + * @author esofer + */ +public class ConstraintValueDoNotMatchPropertyTypeException extends ConstraintFunctionalException { + + private static final long serialVersionUID = 4342613849660957651L; + + public ConstraintValueDoNotMatchPropertyTypeException(String message) { + super(message); + } + + public ConstraintValueDoNotMatchPropertyTypeException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintValueDoNotMatchPropertyTypeException(String message, Throwable cause, + ConstraintInformation constraintInformation) { + super(message, cause); + this.constraintInformation = constraintInformation; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java new file mode 100644 index 0000000000..7fce63841d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.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.model.tosca.constraints.exception; + +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil.ConstraintInformation; + +/** + * Exception happened while user violated a predefined constraint + * + * @author mkv + * + */ +public class ConstraintViolationException extends ConstraintFunctionalException { + + private static final long serialVersionUID = 1L; + + public ConstraintViolationException(String message) { + super(message); + } + + public ConstraintViolationException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintViolationException(String message, Throwable cause, ConstraintInformation constraintInformation) { + super(message, cause); + this.constraintInformation = constraintInformation; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java new file mode 100644 index 0000000000..1454306e89 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.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.be.model.tosca.constraints.exception; + +/** + * All functional exception which is related to user input must go here. It's a + * checked exception to force error handling and checking. + * + * @author mkv + * + */ +public class FunctionalException extends Exception { + + private static final long serialVersionUID = 6712845685798792493L; + + public FunctionalException(String message, Throwable cause) { + super(message, cause); + } + + public FunctionalException(String message) { + super(message); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java new file mode 100644 index 0000000000..2b231d98e3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.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.model.tosca.constraints.exception; + +/** + * Exception thrown when the user defines invalid custom property constraint + * + * @author mkv + * + */ +public class InvalidPropertyConstraintImplementationException extends ConstraintTechnicalException { + + private static final long serialVersionUID = 2797550944328544706L; + + public InvalidPropertyConstraintImplementationException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidPropertyConstraintImplementationException(String message) { + super(message); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java new file mode 100644 index 0000000000..1bddeea69b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.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.model.tosca.constraints.exception; + +/** + * Base class for all Alien technical exception + * + * @author mkv + * + */ +public abstract class TechnicalException extends RuntimeException { + + private static final long serialVersionUID = -9152473183025390161L; + + public TechnicalException(String message, Throwable cause) { + super(message, cause); + } + + public TechnicalException(String message) { + super(message); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java new file mode 100644 index 0000000000..f721efb3c9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class BooleanConverter implements ToscaValueConverter { + private static BooleanConverter booleanConverter = new BooleanConverter(); + + public static BooleanConverter getInstance() { + return booleanConverter; + } + + private BooleanConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map dataTypes) { + return Boolean.valueOf(value); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java new file mode 100644 index 0000000000..c190298b52 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class DefaultConverter implements PropertyValueConverter { + + private static DefaultConverter defaultConverter = new DefaultConverter(); + + public static DefaultConverter getInstance() { + return defaultConverter; + } + + private DefaultConverter() { + + } + + @Override + public String convert(String value, String innerType, Map dataTypes) { + return value; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java new file mode 100644 index 0000000000..d3edd9b8bf --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class FloatConverter implements ToscaValueConverter { + private static FloatConverter floatConverter = new FloatConverter(); + + public static FloatConverter getInstance() { + return floatConverter; + } + + private FloatConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map dataTypes) { + return Double.parseDouble(value); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java new file mode 100644 index 0000000000..147b2e9c52 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.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.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class HeatBooleanConverter implements PropertyValueConverter { + + private static HeatBooleanConverter booleanConverter = new HeatBooleanConverter(); + + public static HeatBooleanConverter getInstance() { + return booleanConverter; + } + + private HeatBooleanConverter() { + + } + + @Override + public String convert(String value, String innerType, Map dataTypes) { + + if (value == null) { + return null; + } + + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("t") || value.equalsIgnoreCase("on") + || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("y") || value.equalsIgnoreCase("1")) { + return "true"; + } else { + return "false"; + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java new file mode 100644 index 0000000000..a0834791ff --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatCommaDelimitedListConverter implements PropertyValueConverter { + + private static HeatCommaDelimitedListConverter stringConverter = new HeatCommaDelimitedListConverter(); + + public static HeatCommaDelimitedListConverter getInstance() { + return stringConverter; + } + + private HeatCommaDelimitedListConverter() { + + } + + @Override + public String convert(String original, String innerType, Map dataTypes) { + String coverted = ValidationUtils.removeNoneUtf8Chars(original); + coverted = ValidationUtils.removeHtmlTagsOnly(coverted); + coverted = ValidationUtils.normaliseWhitespace(coverted); + coverted = ValidationUtils.stripOctets(coverted); + + return coverted; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java new file mode 100644 index 0000000000..6e077d60a1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatJsonConverter implements PropertyValueConverter { + + private static HeatJsonConverter jsonConverter = new HeatJsonConverter(); + + public static HeatJsonConverter getInstance() { + return jsonConverter; + } + + private HeatJsonConverter() { + + } + + @Override + public String convert(String original, String innerType, Map dataTypes) { + String coverted = ValidationUtils.removeNoneUtf8Chars(original); + coverted = ValidationUtils.removeHtmlTagsOnly(coverted); + coverted = ValidationUtils.normaliseWhitespace(coverted); + coverted = ValidationUtils.stripOctets(coverted); + // As opposed to string converter, keeping the " and ' symbols + return coverted; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java new file mode 100644 index 0000000000..90781be367 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.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.model.tosca.converters; + +import java.math.BigDecimal; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class HeatNumberConverter implements PropertyValueConverter { + + private static HeatNumberConverter numberConverter = new HeatNumberConverter(); + + public static HeatNumberConverter getInstance() { + return numberConverter; + } + + private HeatNumberConverter() { + + } + + @Override + public String convert(String original, String innerType, Map dataTypes) { + + if (original == null) { + return null; + } + + return new BigDecimal(original).toPlainString(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java new file mode 100644 index 0000000000..475db1db7c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatStringConverter implements PropertyValueConverter { + + private static HeatStringConverter stringConverter = new HeatStringConverter(); + + public static HeatStringConverter getInstance() { + return stringConverter; + } + + private HeatStringConverter() { + + } + + @Override + public String convert(String original, String innerType, Map dataTypes) { + String coverted = ValidationUtils.removeNoneUtf8Chars(original); + coverted = ValidationUtils.normaliseWhitespace(coverted); + coverted = ValidationUtils.stripOctets(coverted); + coverted = ValidationUtils.removeHtmlTagsOnly(coverted); + coverted = coverted.replaceAll("\"", "").replaceAll("\'", ""); + + return coverted; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java new file mode 100644 index 0000000000..076e5aceef --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class IntegerConverter implements ToscaValueConverter { + + private static IntegerConverter integerConverter = new IntegerConverter(); + + public static IntegerConverter getInstance() { + return integerConverter; + } + + private IntegerConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map dataTypes) { + return Integer.parseInt(value); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java new file mode 100644 index 0000000000..3879430e06 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.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.model.tosca.converters; + +import java.io.StringReader; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.GsonFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; + +public class JsonConverter implements PropertyValueConverter { + + private static JsonConverter jsonConverter = new JsonConverter(); + + private static JsonParser jsonParser = new JsonParser(); + + private static Gson gson = GsonFactory.getGson(); + + public static JsonConverter getInstance() { + return jsonConverter; + } + + private JsonConverter() { + + } + + @Override + public String convert(String value, String innerType, Map dataTypes) { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + JsonElement jsonElement = jsonParser.parse(jsonReader); + if (jsonElement.isJsonPrimitive()) { + return value; + } + return gson.toJson(jsonElement); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java new file mode 100644 index 0000000000..8265cc2690 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java @@ -0,0 +1,217 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.converters; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.ListValidator; +import org.openecomp.sdc.common.util.GsonFactory; +import org.openecomp.sdc.common.util.JsonUtils; +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.JsonParseException; +import com.google.gson.JsonParser; + +import fj.data.Either; + +public class ListConverter implements PropertyValueConverter { + + private static ListConverter listConverter = new ListConverter(); + private static Gson gson = GsonFactory.getGson(); + private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName()); + + DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + private static JsonParser jsonParser = new JsonParser(); + + public static ListConverter getInstance() { + return listConverter; + } + + @Override + public String convert(String value, String innerType, Map dataTypes) { + Either convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes); + if (convertWithErrorResult.isRight()) { + return null; + } + + return convertWithErrorResult.left().value(); + } + + public Either convertWithErrorResult(String value, String innerType, + Map dataTypes) { + if (value == null || innerType == null) { + return Either.left(value); + } + + PropertyValueConverter innerConverter; + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType != null) { + PropertyValueConverter innerConverter1; + switch (innerToscaType) { + case STRING: + innerConverter1 = ToscaPropertyType.STRING.getConverter(); + break; + case INTEGER: + innerConverter1 = ToscaPropertyType.INTEGER.getConverter(); + break; + case FLOAT: + innerConverter1 = ToscaPropertyType.FLOAT.getConverter(); + break; + case BOOLEAN: + innerConverter1 = ToscaPropertyType.BOOLEAN.getConverter(); + break; + case JSON: + innerConverter1 = ToscaPropertyType.JSON.getConverter(); + break; + default: + log.debug("inner Tosca Type is unknown"); + return Either.left(value); + } + innerConverter = innerConverter1; + } else { + log.debug("inner Tosca Type {} ia a complex data type.", innerType); + + Either validateComplexInnerType = convertComplexInnerType(value, innerType, dataTypes); + + return validateComplexInnerType; + } + + try { + ArrayList newList = new ArrayList(); + + JsonArray jo = (JsonArray) jsonParser.parse(value); + int size = jo.size(); + for (int i = 0; i < size; i++) { + JsonElement currentValue = jo.get(i); + String element = JsonUtils.toString(currentValue); + + if (element == null || element.isEmpty()) { + continue; + } + element = innerConverter.convert(element, null, dataTypes); + newList.add(element); + } + + switch (innerToscaType) { + case STRING: + value = gson.toJson(newList); + break; + case INTEGER: + List intList = new ArrayList(); + + for (String str : newList) { + int base = 10; + if (str.contains("0x")) { + str = str.replaceFirst("0x", ""); + base = 16; + } + if (str.contains("0o")) { + str = str.replaceFirst("0o", ""); + base = 8; + } + intList.add(new BigInteger(str, base)); + } + value = gson.toJson(intList); + break; + case FLOAT: + value = "["; + for (String str : newList) { + value += str + ","; + } + value = value.substring(0, value.length() - 1); + value += "]"; + break; + case BOOLEAN: + List boolList = new ArrayList(); + for (String str : newList) { + boolList.add(Boolean.valueOf(str)); + } + value = gson.toJson(boolList); + break; + default: + value = gson.toJson(newList); + log.debug("inner Tosca Type unknown : {}", innerToscaType); + } + + } catch (JsonParseException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter"); + return Either.right(false); + } + + return Either.left(value); + } + + private Either convertComplexInnerType(String value, String innerType, + Map allDataTypes) { + + DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType); + if (dataTypeDefinition == null) { + log.debug("Cannot find data type {}", innerType); + return Either.right(false); + } + + List newList = new ArrayList<>(); + + try { + + JsonArray jo = (JsonArray) jsonParser.parse(value); + int size = jo.size(); + for (int i = 0; i < size; i++) { + JsonElement currentValue = jo.get(i); + + if (currentValue != null) { + + String element = JsonUtils.toString(currentValue); + + ImmutablePair validateAndUpdate = dataTypeValidatorConverter + .validateAndUpdate(element, dataTypeDefinition, allDataTypes); + if (validateAndUpdate.right.booleanValue() == false) { + log.debug("Cannot parse value {} from type {} in list position {}", currentValue, innerType, i); + return Either.right(false); + } + JsonElement newValue = validateAndUpdate.left; + newList.add(newValue); + } + } + } catch (Exception e) { + log.debug("Failed to parse the value {} of list parameter.", value); + return Either.right(false); + } + value = gson.toJson(newList); + return Either.left(value); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java new file mode 100644 index 0000000000..f33be29327 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class LowerCaseConverter implements PropertyValueConverter { + + private static LowerCaseConverter booleanConverter = new LowerCaseConverter(); + + public static LowerCaseConverter getInstance() { + return booleanConverter; + } + + private LowerCaseConverter() { + + } + + @Override + public String convert(String value, String innerType, Map dataTypes) { + + if (value == null) { + return null; + } + return value.toLowerCase(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java new file mode 100644 index 0000000000..921c6d0d41 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java @@ -0,0 +1,249 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.converters; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.ListValidator; +import org.openecomp.sdc.common.util.GsonFactory; +import org.openecomp.sdc.common.util.JsonUtils; +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.google.gson.JsonParseException; +import com.google.gson.JsonParser; + +import fj.data.Either; + +public class MapConverter implements PropertyValueConverter { + + private static MapConverter mapConverter = new MapConverter(); + private static Gson gson = GsonFactory.getGson(); + private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName()); + + DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + private static JsonParser jsonParser = new JsonParser(); + + public static MapConverter getInstance() { + return mapConverter; + } + + public String convert(String value, String innerType, Map dataTypes) { + + Either convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes); + if (convertWithErrorResult.isRight()) { + return null; + } + + return convertWithErrorResult.left().value(); + } + + public Either convertWithErrorResult(String value, String innerType, + Map dataTypes) { + + if (value == null || value == "" || innerType == null) { + return Either.left(value); + } + + PropertyValueConverter innerConverter; + PropertyValueConverter keyConverter = ToscaPropertyType.STRING.getConverter(); + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType != null) { + switch (innerToscaType) { + case STRING: + innerConverter = ToscaPropertyType.STRING.getConverter(); + break; + case INTEGER: + innerConverter = ToscaPropertyType.INTEGER.getConverter(); + break; + case FLOAT: + innerConverter = ToscaPropertyType.FLOAT.getConverter(); + break; + case BOOLEAN: + innerConverter = ToscaPropertyType.BOOLEAN.getConverter(); + break; + case JSON: + innerConverter = ToscaPropertyType.JSON.getConverter(); + break; + default: + log.debug("inner Tosca Type is unknown"); + return Either.left(value); + } + + } else { + + log.debug("inner Tosca Type {} ia a complex data type.", innerType); + + Either validateComplexInnerType = convertComplexInnerType(value, innerType, keyConverter, + dataTypes); + + return validateComplexInnerType; + + } + + try { + Map newMap = new HashMap(); + + JsonElement jsonObject = jsonParser.parse(value); + JsonObject asJsonObject = jsonObject.getAsJsonObject(); + Set> entrySet = asJsonObject.entrySet(); + for (Entry entry : entrySet) { + String key = entry.getKey(); + JsonElement jsonValue = entry.getValue(); + + key = keyConverter.convert(entry.getKey(), null, dataTypes); + + String element = JsonUtils.toString(jsonValue); + + String val = innerConverter.convert(element, null, dataTypes); + newMap.put(key, val); + } + + String objVal; + switch (innerToscaType) { + case STRING: + value = gson.toJson(newMap); + break; + case INTEGER: + String key = null; + Map intMap = new HashMap(); + for (Map.Entry entry : newMap.entrySet()) { + objVal = entry.getValue(); + key = entry.getKey(); + if (objVal != null) { + intMap.put(key, Integer.valueOf(objVal.toString())); + } else { + intMap.put(key, null); + } + + } + value = gson.toJson(intMap); + break; + case FLOAT: + value = "{"; + for (Map.Entry entry : newMap.entrySet()) { + objVal = entry.getValue(); + if (objVal == null) { + objVal = "null"; + } + key = entry.getKey(); + value += "\"" + key + "\":" + objVal.toString() + ","; + } + value = value.substring(0, value.length() - 1); + value += "}"; + break; + case BOOLEAN: + Map boolMap = new HashMap(); + for (Map.Entry entry : newMap.entrySet()) { + objVal = entry.getValue(); + key = entry.getKey(); + if (objVal != null) { + boolMap.put(key, Boolean.valueOf(objVal.toString())); + } else { + boolMap.put(key, null); + } + } + value = gson.toJson(boolMap); + break; + default: + value = gson.toJson(newMap); + log.debug("inner Tosca Type unknown : {}", innerToscaType); + } + } catch (JsonParseException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Map Converter"); + return Either.right(false); + } + + return Either.left(value); + + } + + /** + * convert the json value of map when the inner type is a complex data type + * + * @param value + * @param innerType + * @param keyConverter + * @param allDataTypes + * @return + */ + private Either convertComplexInnerType(String value, String innerType, + PropertyValueConverter keyConverter, Map allDataTypes) { + + DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType); + if (dataTypeDefinition == null) { + log.debug("Cannot find data type {}", innerType); + return Either.right(false); + } + + Map newMap = new HashMap(); + + try { + + JsonElement jsonObject = jsonParser.parse(value); + JsonObject asJsonObject = jsonObject.getAsJsonObject(); + Set> entrySet = asJsonObject.entrySet(); + for (Entry entry : entrySet) { + String currentKey = keyConverter.convert(entry.getKey(), null, allDataTypes); + + JsonElement currentValue = entry.getValue(); + + if (currentValue != null) { + + String element = JsonUtils.toString(currentValue); + + ImmutablePair validateAndUpdate = dataTypeValidatorConverter + .validateAndUpdate(element, dataTypeDefinition, allDataTypes); + if (validateAndUpdate.right.booleanValue() == false) { + log.debug("Cannot parse value {} from type {} of key {}", currentValue, innerType, currentKey); + return Either.right(false); + } + JsonElement newValue = validateAndUpdate.left; + newMap.put(currentKey, newValue); + } else { + newMap.put(currentKey, null); + } + } + + } catch (Exception e) { + log.debug("Cannot parse value {} of map from inner type {}", value, innerType); + return Either.right(false); + } + + value = gson.toJson(newMap); + return Either.left(value); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java new file mode 100644 index 0000000000..254785fe8a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public interface PropertyValueConverter { + + String convert(String value, String innerType, Map dataTypes); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java new file mode 100644 index 0000000000..f5a7ff632e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.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.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class StringConvertor implements PropertyValueConverter { + + private static StringConvertor stringConverter = new StringConvertor(); + + public static StringConvertor getInstance() { + return stringConverter; + } + + private StringConvertor() { + + } + + @Override + public String convert(String original, String innerType, Map dataTypes) { + if (original == null) { + return null; + } + String coverted = ValidationUtils.removeNoneUtf8Chars(original); + + // coverted = ValidationUtils.convertHtmlTagsToEntities(coverted); + coverted = ValidationUtils.normaliseWhitespace(coverted); + coverted = ValidationUtils.stripOctets(coverted); + coverted = ValidationUtils.removeHtmlTagsOnly(coverted); + + return coverted; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java new file mode 100644 index 0000000000..977415b909 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.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.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaBooleanConverter implements PropertyValueConverter { + + private static ToscaBooleanConverter booleanConverter = new ToscaBooleanConverter(); + + public static ToscaBooleanConverter getInstance() { + return booleanConverter; + } + + private ToscaBooleanConverter() { + + } + + @Override + public String convert(String value, String innerType, Map dataTypes) { + + if (value == null) { + return null; + } + + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("yes") + || value.equalsIgnoreCase("y")) { + return "true"; + } else { + return "false"; + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java new file mode 100644 index 0000000000..5d7f98e438 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.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.model.tosca.converters; + +import java.math.BigDecimal; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaFloatConverter implements PropertyValueConverter { + + private static ToscaFloatConverter numberConverter = new ToscaFloatConverter(); + + public static ToscaFloatConverter getInstance() { + return numberConverter; + } + + private ToscaFloatConverter() { + + } + + @Override + public String convert(String original, String innerType, Map dataTypes) { + if (original == null) { + return null; + } + if (original.contains("f") || original.contains("F")) + original = original.toLowerCase().replaceFirst("f", ""); + return new BigDecimal(original).toPlainString(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java new file mode 100644 index 0000000000..d70088e044 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.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.be.model.tosca.converters; + +import java.io.StringReader; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; + +public class ToscaJsonValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter { + private static ToscaJsonValueConverter toscaJsonConverter = new ToscaJsonValueConverter(); + + public static ToscaJsonValueConverter getInstance() { + return toscaJsonConverter; + } + + private ToscaJsonValueConverter() { + + } + + JsonParser jsonParser = new JsonParser(); + + @Override + public Object convertToToscaValue(String value, String innerType, Map dataTypes) { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + JsonElement jsonElement = jsonParser.parse(jsonReader); + if (jsonElement.isJsonPrimitive()) { + return value; + } + return handleComplexJsonValue(jsonElement); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java new file mode 100644 index 0000000000..043446e783 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.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.model.tosca.converters; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.JsonReader; + +public class ToscaListValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter { + private static ToscaListValueConverter listConverter = new ToscaListValueConverter(); + private JsonParser jsonParser = new JsonParser(); + private static Logger log = LoggerFactory.getLogger(ToscaListValueConverter.class.getName()); + + public static ToscaListValueConverter getInstance() { + return listConverter; + } + + private ToscaListValueConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map dataTypes) { + if (value == null) { + return null; + } + try { + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + ToscaValueConverter innerConverter = null; + boolean isScalar = true; + if (innerToscaType != null) { + innerConverter = innerToscaType.getValueConverter(); + } else { + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + + if (dataTypeDefinition != null) { + ToscaPropertyType toscaPropertyType = null; + if ((toscaPropertyType = isScalarType(dataTypeDefinition)) != null) { + innerConverter = toscaPropertyType.getValueConverter(); + } else { + isScalar = false; + innerConverter = ToscaMapValueConverter.getInstance(); + } + } else { + log.debug("inner Tosca Type is null"); + return value; + } + } + JsonElement jsonElement = null; + try { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + + jsonElement = jsonParser.parse(jsonReader); + } catch (JsonSyntaxException e) { + log.debug("convertToToscaValue failed to parse json value :", e); + return null; + } + if (jsonElement == null || true == jsonElement.isJsonNull()) { + log.debug("convertToToscaValue json element is null"); + return null; + } + if (jsonElement.isJsonArray() == false) { + // get_input all array like get_input: qrouter_names + return handleComplexJsonValue(jsonElement); + } + JsonArray asJsonArray = jsonElement.getAsJsonArray(); + + ArrayList toscaList = new ArrayList(); + final boolean isScalarF = isScalar; + final ToscaValueConverter innerConverterFinal = innerConverter; + asJsonArray.forEach(e -> { + Object convertedValue = null; + if (isScalarF) { + log.debug("try to convert scalar value {}", e.getAsString()); + if (e.getAsString() == null) { + convertedValue = null; + } else { + JsonElement singleElement = jsonParser.parse(e.getAsString()); + if (singleElement.isJsonPrimitive()) { + convertedValue = innerConverterFinal.convertToToscaValue(e.getAsString(), innerType, + dataTypes); + } else { + convertedValue = handleComplexJsonValue(singleElement); + } + } + } else { + JsonObject asJsonObject = e.getAsJsonObject(); + Set> entrySet = asJsonObject.entrySet(); + + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + Map allProperties = getAllProperties(dataTypeDefinition); + Map toscaObjectPresentation = new HashMap<>(); + // log.debug("try to convert datatype value {}", + // e.getAsString()); + + for (Entry entry : entrySet) { + String propName = entry.getKey(); + + JsonElement elementValue = entry.getValue(); + PropertyDefinition propertyDefinition = allProperties.get(propName); + if (propertyDefinition == null) { + log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName()); + continue; + // return null; + } + String type = propertyDefinition.getType(); + ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type); + Object convValue; + if (propertyType != null) { + if (elementValue.isJsonPrimitive()) { + ToscaValueConverter valueConverter = propertyType.getValueConverter(); + convValue = valueConverter.convertToToscaValue(elementValue.getAsString(), type, + dataTypes); + } else { + if (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(propertyType)) { + ToscaValueConverter valueConverter = propertyType.getValueConverter(); + String json = gson.toJson(elementValue); + String innerTypeRecursive = propertyDefinition.getSchema().getProperty().getType(); + convValue = valueConverter.convertToToscaValue(json, innerTypeRecursive, dataTypes); + } else { + convValue = handleComplexJsonValue(elementValue); + } + } + } else { + String json = gson.toJson(elementValue); + convValue = convertToToscaValue(json, type, dataTypes); + } + toscaObjectPresentation.put(propName, convValue); + } + convertedValue = toscaObjectPresentation; + } + toscaList.add(convertedValue); + }); + return toscaList; + } catch ( + + JsonParseException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter"); + return null; + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java new file mode 100644 index 0000000000..601d8f0fc8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.converters; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.JsonReader; + +public class ToscaMapValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter { + private static ToscaMapValueConverter mapConverter = new ToscaMapValueConverter(); + + private JsonParser jsonParser = new JsonParser(); + private static Logger log = LoggerFactory.getLogger(ToscaMapValueConverter.class.getName()); + + public static ToscaMapValueConverter getInstance() { + return mapConverter; + } + + private ToscaMapValueConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map dataTypes) { + if (value == null) { + return value; + } + try { + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + ToscaValueConverter innerConverter = null; + boolean isScalar = true; + if (innerToscaType != null) { + innerConverter = innerToscaType.getValueConverter(); + } else { + + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + if (dataTypeDefinition != null) { + ToscaPropertyType toscaPropertyType = null; + if ((toscaPropertyType = isScalarType(dataTypeDefinition)) != null) { + innerConverter = toscaPropertyType.getValueConverter(); + } else { + isScalar = false; + } + } else { + // TODO handle getinput + log.debug("inner Tosca Type is null"); + return value; + } + + } + JsonElement jsonElement = null; + try { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + + jsonElement = jsonParser.parse(jsonReader); + + } catch (JsonSyntaxException e) { + log.debug("convertToToscaValue failed to parse json value :", e); + return null; + } + if (jsonElement == null || true == jsonElement.isJsonNull()) { + log.debug("convertToToscaValue json element is null"); + return null; + } + JsonObject asJsonObject = jsonElement.getAsJsonObject(); + Set> entrySet = asJsonObject.entrySet(); + + Map toscaMap = new HashMap<>(); + final boolean isScalarF = isScalar; + final ToscaValueConverter innerConverterFinal = innerConverter; + entrySet.forEach(e -> { + log.debug("try convert element {}", e.getValue()); + Object convertedValue = convertDataTypeToToscaMap(innerType, dataTypes, innerConverterFinal, isScalarF, + e.getValue()); + toscaMap.put(e.getKey(), convertedValue); + }); + return toscaMap; + } catch (JsonParseException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter"); + return null; + } + } + + public Object convertDataTypeToToscaMap(String innerType, Map dataTypes, + ToscaValueConverter innerConverter, final boolean isScalarF, JsonElement entryValue) { + Object convertedValue = null; + if (isScalarF && entryValue.isJsonPrimitive()) { + log.debug("try convert scalar value {}", entryValue.getAsString()); + if (entryValue.getAsString() == null) { + convertedValue = null; + } else { + convertedValue = innerConverter.convertToToscaValue(entryValue.getAsString(), innerType, dataTypes); + } + } else { + JsonObject asJsonObjectIn = entryValue.getAsJsonObject(); + Set> entrySetIn = asJsonObjectIn.entrySet(); + + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + Map allProperties = getAllProperties(dataTypeDefinition); + Map toscaObjectPresentation = new HashMap<>(); + + for (Entry entry : entrySetIn) { + String propName = entry.getKey(); + + JsonElement elementValue = entry.getValue(); + Object convValue; + if (isScalarF == false) { + PropertyDefinition propertyDefinition = allProperties.get(propName); + if (propertyDefinition == null && isScalarF) { + log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName()); + continue; + } + + String type = propertyDefinition.getType(); + ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type); + if (propertyType != null) { + if (elementValue.isJsonPrimitive()) { + ToscaValueConverter valueConverter = propertyType.getValueConverter(); + convValue = valueConverter.convertToToscaValue(elementValue.getAsString(), type, dataTypes); + } else { + if (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(propertyType)) { + ToscaValueConverter valueConverter = propertyType.getValueConverter(); + String json = gson.toJson(elementValue); + String innerTypeRecursive = propertyDefinition.getSchema().getProperty().getType(); + convValue = valueConverter.convertToToscaValue(json, innerTypeRecursive, dataTypes); + } else { + convValue = handleComplexJsonValue(elementValue); + } + } + } else { + convValue = convertToToscaValue(elementValue.getAsString(), type, dataTypes); + } + } else { + if (elementValue.isJsonPrimitive()) { + convValue = json2JavaPrimitive(elementValue.getAsJsonPrimitive()); + } else { + convValue = handleComplexJsonValue(elementValue); + } + } + toscaObjectPresentation.put(propName, convValue); + } + convertedValue = toscaObjectPresentation; + } + return convertedValue; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java new file mode 100644 index 0000000000..e228d256c2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaStringConvertor implements ToscaValueConverter { + private static ToscaStringConvertor stringConverter = new ToscaStringConvertor(); + + public static ToscaStringConvertor getInstance() { + return stringConverter; + } + + private ToscaStringConvertor() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map dataTypes) { + return value; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java new file mode 100644 index 0000000000..e886327481 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java @@ -0,0 +1,153 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.converters; + +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 java.util.Set; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +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.JsonPrimitive; + +public class ToscaValueBaseConverter { + protected Gson gson = new Gson(); + private static Logger log = LoggerFactory.getLogger(ToscaValueBaseConverter.class.getName()); + + protected Map getAllProperties(DataTypeDefinition dataTypeDefinition) { + + Map allParentsProps = new HashMap<>(); + + while (dataTypeDefinition != null) { + + List currentParentsProps = dataTypeDefinition.getProperties(); + if (currentParentsProps != null) { + currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p)); + } + + dataTypeDefinition = dataTypeDefinition.getDerivedFrom(); + } + + return allParentsProps; + } + + public ToscaPropertyType isScalarType(DataTypeDefinition dataTypeDef) { + + ToscaPropertyType result = null; + + DataTypeDefinition dataType = dataTypeDef; + + while (dataType != null) { + + String name = dataType.getName(); + ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name); + if (typeIfScalar != null) { + result = typeIfScalar; + break; + } + + dataType = dataType.getDerivedFrom(); + } + + return result; + } + + public Object handleComplexJsonValue(JsonElement elementValue) { + Object jsonValue = null; + + Map value = new HashMap(); + if ( elementValue.isJsonObject() ){ + JsonObject jsonOb = elementValue.getAsJsonObject(); + Set> entrySet = jsonOb.entrySet(); + Iterator> iteratorEntry = entrySet.iterator(); + while (iteratorEntry.hasNext()) { + Entry entry = iteratorEntry.next(); + if (entry.getValue().isJsonArray()) { + List array = handleJsonArray(entry.getValue()); + value.put(entry.getKey(), array); + } else { + Object object; + if (entry.getValue().isJsonPrimitive()) { + object = json2JavaPrimitive(entry.getValue().getAsJsonPrimitive()); + } else { + object = handleComplexJsonValue(entry.getValue()); + } + value.put(entry.getKey(), object); + } + } + jsonValue = value; + }else{ + if ( elementValue.isJsonArray() ){ + jsonValue = handleJsonArray(elementValue); + }else{ + log.debug("not supported json type {} ",elementValue); + } + } + + return jsonValue; + } + + private List handleJsonArray(JsonElement entry) { + List array = new ArrayList<>(); + JsonArray jsonArray = entry.getAsJsonArray(); + Iterator iterator = jsonArray.iterator(); + while (iterator.hasNext()) { + Object object; + JsonElement element = iterator.next(); + if (element.isJsonPrimitive()) { + object = json2JavaPrimitive(element.getAsJsonPrimitive()); + } else { + object = handleComplexJsonValue(element); + } + array.add(object); + } + return array; + } + + public Object json2JavaPrimitive(JsonPrimitive prim) { + if (prim.isBoolean()) { + return prim.getAsBoolean(); + } else if (prim.isString()) { + return prim.getAsString(); + } else if (prim.isNumber()) { + String strRepesentation = prim.getAsString(); + if (strRepesentation.contains(".")) { + return prim.getAsDouble(); + } else { + return prim.getAsInt(); + } + } else { + throw new IllegalStateException(); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java new file mode 100644 index 0000000000..1b5d4697be --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public interface ToscaValueConverter { + Object convertToToscaValue(String value, String innerType, Map dataTypes); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java new file mode 100644 index 0000000000..b6eb24276e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.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.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaValueDefaultConverter implements ToscaValueConverter { + private static ToscaValueDefaultConverter deafultConverter = new ToscaValueDefaultConverter(); + + public static ToscaValueDefaultConverter getInstance() { + return deafultConverter; + } + + private ToscaValueDefaultConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map dataTypes) { + return value; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java new file mode 100644 index 0000000000..def0e7c391 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.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.be.model.tosca.validators; + +import java.util.Arrays; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class BooleanValidator implements PropertyTypeValidator { + + private static BooleanValidator booleanValidator = new BooleanValidator(); + private static String[] validValues = { "true", "t", "on", "yes", "y", "1", "false", "f", "off", "no", "n", "0" }; + + public static BooleanValidator getInstance() { + return booleanValidator; + } + + private BooleanValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + return (Arrays.stream(validValues).filter(str -> str.equalsIgnoreCase(value)).toArray().length == 1); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, null, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java new file mode 100644 index 0000000000..d376a1ec13 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java @@ -0,0 +1,499 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.validators; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.lang3.tuple.ImmutablePair; +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.be.model.tosca.converters.PropertyValueConverter; +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.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSyntaxException; + +public class DataTypeValidatorConverter { + + private static DataTypeValidatorConverter dataTypeValidatorConverter = new DataTypeValidatorConverter(); + + public static DataTypeValidatorConverter getInstance() { + return dataTypeValidatorConverter; + } + + private DataTypeValidatorConverter() { + + } + + private static Logger log = LoggerFactory.getLogger(DataTypeValidatorConverter.class.getName()); + + JsonParser jsonParser = new JsonParser(); + + Gson gson = new Gson(); + + ImmutablePair falseResult = new ImmutablePair(null, false); + ImmutablePair trueEmptyResult = new ImmutablePair(null, true); + + ImmutablePair trueStringEmptyResult = new ImmutablePair(null, true); + ImmutablePair falseStringEmptyResult = new ImmutablePair(null, true); + + private ToscaPropertyType isDataTypeDerviedFromScalarType(DataTypeDefinition dataTypeDef) { + + ToscaPropertyType result = null; + + DataTypeDefinition dataType = dataTypeDef; + + while (dataType != null) { + + String name = dataType.getName(); + ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name); + if (typeIfScalar != null) { + result = typeIfScalar; + break; + } + + dataType = dataType.getDerivedFrom(); + } + + return result; + } + + private ImmutablePair validateAndUpdate(JsonElement jsonElement, + DataTypeDefinition dataTypeDefinition, Map allDataTypes) { + + Map allProperties = getAllProperties(dataTypeDefinition); + + ToscaPropertyType toscaPropertyType = null; + if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) { + + PropertyTypeValidator validator = toscaPropertyType.getValidator(); + PropertyValueConverter converter = toscaPropertyType.getConverter(); + if (jsonElement == null || true == jsonElement.isJsonNull()) { + boolean valid = validator.isValid(null, null, allDataTypes); + if (false == valid) { + log.trace("Failed in validation of property {} from type {}", dataTypeDefinition.getName(), dataTypeDefinition.getName()); + return falseResult; + } + return new ImmutablePair(jsonElement, true); + + } else { + if (true == jsonElement.isJsonPrimitive()) { + String value = null; + if (jsonElement != null) { + if (jsonElement.toString().isEmpty()) { + value = ""; + } else { + value = jsonElement.toString(); + } + } + boolean valid = validator.isValid(value, null, null); + if (false == valid) { + log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value); + return falseResult; + } + + String convertedValue = converter.convert(value, null, allDataTypes); + JsonElement element = null; + try { + element = jsonParser.parse(convertedValue); + } catch (JsonSyntaxException e) { + log.debug("Failed to parse value {} of property {}. {}", convertedValue, dataTypeDefinition.getName(), e); + return falseResult; + } + + return new ImmutablePair(element, true); + + } else { + // MAP, LIST, OTHER types cannot be applied data type + // definition scalar type. We currently cannot derived from + // map/list. (cannot add the entry schema to it) + log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName()); + + return falseResult; + } + } + } else { + + if (jsonElement == null || jsonElement.isJsonNull()) { + + return new ImmutablePair(jsonElement, true); + + } else { + + if (jsonElement.isJsonObject()) { + + JsonObject buildJsonObject = new JsonObject(); + + JsonObject asJsonObject = jsonElement.getAsJsonObject(); + Set> entrySet = asJsonObject.entrySet(); + + for (Entry entry : entrySet) { + String propName = entry.getKey(); + + JsonElement elementValue = entry.getValue(); + + PropertyDefinition propertyDefinition = allProperties.get(propName); + if (propertyDefinition == null) { + log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName()); + return falseResult; + } + String type = propertyDefinition.getType(); + boolean isScalarType = ToscaPropertyType.isScalarType(type); + + if (true == isScalarType) { + ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type); + if (propertyType == null) { + log.debug("cannot find the {} under default tosca property types", type); + return falseResult; + } + PropertyTypeValidator validator = propertyType.getValidator(); + String innerType = null; + if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) { + if (propertyDefinition.getSchema() != null + && propertyDefinition.getSchema().getProperty() != null) { + innerType = propertyDefinition.getSchema().getProperty().getType(); + if (innerType == null) { + log.debug("Property type {} must have inner type in its declaration.", propertyType); + return falseResult; + } + } + } + + String value = null; + if (elementValue != null) { + if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) { + value = ""; + } else { + value = elementValue.toString(); + } + } + + boolean isValid = validator.isValid(value, innerType, allDataTypes); + if (false == isValid) { + log.debug("Failed to validate the value {} from type {}", value, propertyType); + return falseResult; + } + + PropertyValueConverter converter = propertyType.getConverter(); + String convertedValue = converter.convert(value, innerType, allDataTypes); + + JsonElement element = null; + if (convertedValue != null) { + if (convertedValue.isEmpty()) { + element = new JsonPrimitive(""); + } else { + try { + element = jsonParser.parse(convertedValue); + } catch (JsonSyntaxException e) { + log.debug("Failed to parse value {} of type {}. {}", convertedValue, propertyType, e); + return falseResult; + } + } + } + buildJsonObject.add(propName, element); + + } else { + + DataTypeDefinition typeDefinition = allDataTypes.get(type); + if (typeDefinition == null) { + log.debug("The data type {] cannot be found in the given data type list.", type); + return falseResult; + } + + ImmutablePair isValid = validateAndUpdate(elementValue, + typeDefinition, allDataTypes); + + if (false == isValid.getRight().booleanValue()) { + log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName()); + return falseResult; + } + + buildJsonObject.add(propName, isValid.getLeft()); + } + + } + + return new ImmutablePair(buildJsonObject, true); + } else { + log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName()); + return falseResult; + } + + } + } + + } + + public ImmutablePair validateAndUpdate(String value, DataTypeDefinition dataTypeDefinition, + Map allDataTypes) { + + ImmutablePair result = falseResult; + + if (value == null || value.isEmpty()) { + return trueEmptyResult; + } + + JsonElement jsonElement = null; + try { + jsonElement = jsonParser.parse(value); + } catch (JsonSyntaxException e) { + return falseResult; + } + + result = validateAndUpdate(jsonElement, dataTypeDefinition, allDataTypes); + + return result; + } + + private Map getAllProperties(DataTypeDefinition dataTypeDefinition) { + + Map allParentsProps = new HashMap(); + + while (dataTypeDefinition != null) { + + List currentParentsProps = dataTypeDefinition.getProperties(); + if (currentParentsProps != null) { + currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p)); + } + + dataTypeDefinition = dataTypeDefinition.getDerivedFrom(); + } + + return allParentsProps; + } + + private String getValueFromJsonElement(JsonElement jsonElement) { + String value = null; + + if (jsonElement == null || jsonElement.isJsonNull()) { + value = PropertyOperation.EMPTY_VALUE; + } else { + if (jsonElement.toString().isEmpty()) { + value = ""; + } else { + value = jsonElement.toString(); + } + } + + return value; + } + + public boolean isValid(String value, DataTypeDefinition dataTypeDefinition, + Map allDataTypes) { + + boolean result = false; + + if (value == null || value.isEmpty()) { + return true; + } + + JsonElement jsonElement = null; + try { + jsonElement = jsonParser.parse(value); + } catch (JsonSyntaxException e) { + log.debug("Failed to parse the value {} from type {}. {}", value, dataTypeDefinition, e); + return false; + } + + result = isValid(jsonElement, dataTypeDefinition, allDataTypes); + + return result; + } + + private boolean isValid(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, + Map allDataTypes) { + + Map allProperties = getAllProperties(dataTypeDefinition); + + ToscaPropertyType toscaPropertyType = null; + if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) { + + PropertyTypeValidator validator = toscaPropertyType.getValidator(); + if (jsonElement == null || true == jsonElement.isJsonNull()) { + boolean valid = validator.isValid(null, null, allDataTypes); + if (false == valid) { + log.trace("Failed in validation of property " + dataTypeDefinition.getName() + " from type " + + dataTypeDefinition.getName()); + return false; + } + + return true; + + } else { + if (true == jsonElement.isJsonPrimitive()) { + String value = null; + if (jsonElement != null) { + if (jsonElement.toString().isEmpty()) { + value = ""; + } else { + value = jsonElement.toString(); + } + } + boolean valid = validator.isValid(value, null, allDataTypes); + if (false == valid) { + log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value); + return false; + } + + return true; + + } else { + // MAP, LIST, OTHER types cannot be applied data type + // definition scalar type. We currently cannot derived from + // map/list. (cannot add the entry schema to it) + log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName()); + + return false; + } + } + } else { + + if (jsonElement == null || jsonElement.isJsonNull()) { + + return true; + + } else { + + if (jsonElement.isJsonObject()) { + + JsonObject asJsonObject = jsonElement.getAsJsonObject(); + Set> entrySet = asJsonObject.entrySet(); + + for (Entry entry : entrySet) { + String propName = entry.getKey(); + + JsonElement elementValue = entry.getValue(); + + PropertyDefinition propertyDefinition = allProperties.get(propName); + if (propertyDefinition == null) { + log.debug("The property {} was not found under data tpye {}", propName, dataTypeDefinition.getName()); + return false; + } + String type = propertyDefinition.getType(); + boolean isScalarType = ToscaPropertyType.isScalarType(type); + + if (true == isScalarType) { + ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type); + if (propertyType == null) { + log.debug("cannot find the {} under default tosca property types", type); + return false; + } + PropertyTypeValidator validator = propertyType.getValidator(); + String innerType = null; + if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) { + if (propertyDefinition.getSchema() != null + && propertyDefinition.getSchema().getProperty() != null) { + innerType = propertyDefinition.getSchema().getProperty().getType(); + if (innerType == null) { + log.debug("Property type {} must have inner type in its decleration.", propertyType); + return false; + } + } + } + + String value = null; + if (elementValue != null) { + if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) { + value = ""; + } else { + value = elementValue.toString(); + } + } + + boolean isValid = validator.isValid(value, innerType, allDataTypes); + if (false == isValid) { + log.debug("Failed to validate the value {} from type {}", value, propertyType); + return false; + } + + } else { + + DataTypeDefinition typeDefinition = allDataTypes.get(type); + if (typeDefinition == null) { + log.debug("The data type {} canot be found in the given data type list.", type); + return false; + } + + boolean isValid = isValid(elementValue, typeDefinition, allDataTypes); + + if (false == isValid) { + log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName()); + return false; + } + + } + + } + + return true; + } else { + log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName()); + return false; + } + + } + } + + } + + // public ImmutablePair + // validateAndUpdateAndReturnString(String value, DataTypeDefinition + // dataTypeDefinition, Map allDataTypes) { + // + // ImmutablePair result = falseResult; + // + // if (value == null || value.isEmpty()) { + // return trueStringEmptyResult; + // } + // + // JsonElement jsonElement = null; + // try { + // jsonElement = jsonParser.parse(value); + // } catch (JsonSyntaxException e) { + // return falseStringEmptyResult; + // } + // + // result = validateAndUpdate(jsonElement, dataTypeDefinition, + // allDataTypes); + // + // if (result.right.booleanValue() == false) { + // log.debug("The value {} of property from type {} is invalid", value, dataTypeDefinition.getName()); + // return new ImmutablePair(value, false); + // } + // + // String valueFromJsonElement = getValueFromJsonElement(result.left); + // + // return new ImmutablePair(valueFromJsonElement, true); + // } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java new file mode 100644 index 0000000000..2518eaa51e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.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.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class FloatValidator implements PropertyTypeValidator { + + private static FloatValidator FloatValidator = new FloatValidator(); + + public static FloatValidator getInstance() { + return FloatValidator; + } + + private FloatValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + try { + Float.parseFloat(value); + } catch (IllegalArgumentException e) { + return false; + } + + return true; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java new file mode 100644 index 0000000000..ec4051e65c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.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.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class HeatBooleanValidator implements PropertyTypeValidator { + + private static HeatBooleanValidator booleanValidator = new HeatBooleanValidator(); + + public static HeatBooleanValidator getInstance() { + return booleanValidator; + } + + private HeatBooleanValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false") || value.equalsIgnoreCase("t") + || value.equalsIgnoreCase("f") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("off") + || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("y") + || value.equalsIgnoreCase("n") || value.equalsIgnoreCase("1") || value.equalsIgnoreCase("0")) { + return true; + } + + return false; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java new file mode 100644 index 0000000000..464dbf0975 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.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.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatCommaDelimitedListValidator implements PropertyTypeValidator { + + private static HeatCommaDelimitedListValidator stringValidator = new HeatCommaDelimitedListValidator(); + + public static HeatCommaDelimitedListValidator getInstance() { + return stringValidator; + } + + private HeatCommaDelimitedListValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + String coverted = ValidationUtils.removeNoneUtf8Chars(value); + return ValidationUtils.validateIsEnglish(coverted); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java new file mode 100644 index 0000000000..37c4a46829 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.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.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class HeatNumberValidator implements PropertyTypeValidator { + + private static HeatNumberValidator numberValidator = new HeatNumberValidator(); + + private static FloatValidator floatValidator = FloatValidator.getInstance(); + private static IntegerValidator integerValidator = IntegerValidator.getInstance(); + + public static HeatNumberValidator getInstance() { + return numberValidator; + } + + private HeatNumberValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + boolean valid = integerValidator.isValid(value, null, allDataTypes); + + if (!valid) { + valid = floatValidator.isValid(value, null, allDataTypes); + } + + return valid; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java new file mode 100644 index 0000000000..0e7b7f6648 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.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.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatStringValidator implements PropertyTypeValidator { + + private static HeatStringValidator stringValidator = new HeatStringValidator(); + + public static HeatStringValidator getInstance() { + return stringValidator; + } + + private HeatStringValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + String coverted = ValidationUtils.removeNoneUtf8Chars(value); + return ValidationUtils.validateIsEnglish(coverted); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java new file mode 100644 index 0000000000..61d321c45e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.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.be.model.tosca.validators; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class IntegerValidator implements PropertyTypeValidator { + + private static IntegerValidator integerValidator = new IntegerValidator(); + + private IntegerValidator() { + } + + public static IntegerValidator getInstance() { + return integerValidator; + } + + private class PatternBase { + public PatternBase(Pattern pattern, Integer base) { + this.pattern = pattern; + this.base = base; + } + + Pattern pattern; + Integer base; + } + + private PatternBase base8Pattern = new PatternBase(Pattern.compile("([-+])?0o([0-7]+)"), 8); + private PatternBase base10Pattern = new PatternBase(Pattern.compile("([-+])?(0|[1-9][0-9]*)"), 10); + private PatternBase base16Pattern = new PatternBase(Pattern.compile("([-+])?0x([0-9a-fA-F]+)"), 16); + + private PatternBase[] patterns = { base10Pattern, base8Pattern, base16Pattern }; + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + for (PatternBase patternBase : patterns) { + Matcher matcher = patternBase.pattern.matcher(value); + Long parsed = null; + if (matcher.matches()) { + try { + parsed = Long.parseLong(matcher.group(2), patternBase.base); + if (matcher.group(1) != null && matcher.group(1).compareTo("-") == 0) { + parsed *= -1; + } + return (Integer.MIN_VALUE <= parsed && parsed <= (Integer.MAX_VALUE)) ? true : false; + } catch (NumberFormatException e) { + return false; + } + } + } + return false; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java new file mode 100644 index 0000000000..164fe62792 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.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.model.tosca.validators; + +import java.io.StringReader; +import java.util.Map; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.common.util.GsonFactory; +import org.openecomp.sdc.common.util.JsonUtils; +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; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.JsonReader; + +public class JsonValidator implements PropertyTypeValidator { + + private static JsonValidator jsonValidator = new JsonValidator(); + + private static Logger log = LoggerFactory.getLogger(JsonValidator.class.getName()); + + private static JsonParser jsonParser = new JsonParser(); + + public static JsonValidator getInstance() { + return jsonValidator; + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || value.isEmpty()) { + return true; + } + try { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + jsonParser.parse(jsonReader); + } catch (JsonSyntaxException e) { + log.debug("Error parsing JSON property", e); + return false; + } + return true; + + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java new file mode 100644 index 0000000000..4b11e26d05 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.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.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class KeyValidator implements PropertyTypeValidator { + + public static final int STRING_MAXIMUM_LENGTH = 100; + + private static KeyValidator keyValidator = new KeyValidator(); + + public static KeyValidator getInstance() { + return keyValidator; + } + + private KeyValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return false; + } + + if (value.length() > STRING_MAXIMUM_LENGTH) { + return false; + } + String coverted = ValidationUtils.removeNoneUtf8Chars(value); + return ValidationUtils.validateIsEnglish(coverted); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java new file mode 100644 index 0000000000..92834690b8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.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.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.common.util.JsonUtils; +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; +import com.google.gson.JsonSyntaxException; + +public class ListValidator implements PropertyTypeValidator { + + private static ListValidator listValidator = new ListValidator(); + + private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName()); + Gson gson = new Gson(); + + private static JsonParser jsonParser = new JsonParser(); + + private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + public static ListValidator getInstance() { + return listValidator; + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + log.debug("Going to validate value {} with inner type {}", value, innerType); + + if (value == null || value == "") { + return true; + } + if (innerType == null) { + return false; + } + + PropertyTypeValidator innerValidator; + + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType != null) { + switch (innerToscaType) { + case STRING: + innerValidator = ToscaPropertyType.STRING.getValidator(); + break; + case INTEGER: + innerValidator = ToscaPropertyType.INTEGER.getValidator(); + break; + case FLOAT: + innerValidator = ToscaPropertyType.FLOAT.getValidator(); + break; + case BOOLEAN: + innerValidator = ToscaPropertyType.BOOLEAN.getValidator(); + break; + case JSON: + innerValidator = ToscaPropertyType.JSON.getValidator(); + break; + default: + log.debug("inner Tosca Type is unknown: {}", innerToscaType); + return false; + } + + } else { + log.debug("inner Tosca Type is: {}", innerType); + + boolean isValid = validateComplexInnerType(value, innerType, allDataTypes); + log.debug("Finish to validate value {} of list with inner type {}. result is: {}", value, innerType, isValid); + return isValid; + } + + try { + JsonArray jo = (JsonArray) jsonParser.parse(value); + int size = jo.size(); + for (int i = 0; i < size; i++) { + JsonElement currentValue = jo.get(i); + String element = JsonUtils.toString(currentValue); + if (!innerValidator.isValid(element, null, allDataTypes)) { + log.debug("validation of element : {} failed", element); + return false; + } + + } + return true; + + } catch (JsonSyntaxException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Validator"); + } + + return false; + + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } + + private boolean validateComplexInnerType(String value, String innerType, + Map allDataTypes) { + + DataTypeDefinition innerDataTypeDefinition = allDataTypes.get(innerType); + if (innerDataTypeDefinition == null) { + log.debug("Data type {} cannot be found in our data types.", innerType); + return false; + } + + try { + + JsonArray jo = (JsonArray) jsonParser.parse(value); + int size = jo.size(); + for (int i = 0; i < size; i++) { + JsonElement currentValue = jo.get(i); + if (currentValue != null) { + String element = JsonUtils.toString(currentValue); + boolean isValid = dataTypeValidatorConverter.isValid(element, innerDataTypeDefinition, + allDataTypes); + if (isValid == false) { + log.debug("Cannot parse value {} from type {} in list parameter", currentValue, innerType); + return false; + } + } + } + + } catch (Exception e) { + log.debug("Error when parsing JSON of object of type ", e); + return false; + } + + return true; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java new file mode 100644 index 0000000000..c8ffc3f4b8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.validators; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.common.util.JsonUtils; +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.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; + +/* + * Property Type Map correct usage: + * null key null value = Yaml reader error +valid key null value = key & value deleted +duplicated keys = last key is taken +mismatch between inner type and values type = returned mismatch in data type +validators and converters works the same as before + +Types: +when written line by line : + key1 : val1 + key2 : val2 +key1 and val does not need " " , even if val1 is a string. + +when written as one line : {"key1":val1 , "key2":val2} +Keys always need " " around them. + */ +public class MapValidator implements PropertyTypeValidator { + + private static MapValidator mapValidator = new MapValidator(); + + private static Logger log = LoggerFactory.getLogger(MapValidator.class.getName()); + Gson gson = new Gson(); + + private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + private static JsonParser jsonParser = new JsonParser(); + + public static MapValidator getInstance() { + return mapValidator; + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || value == "") { + return true; + } + if (innerType == null) { + return false; + } + + PropertyTypeValidator innerValidator; + PropertyTypeValidator keyValidator = ToscaPropertyType.KEY.getValidator(); + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType != null) { + switch (innerToscaType) { + case STRING: + innerValidator = ToscaPropertyType.STRING.getValidator(); + break; + case INTEGER: + innerValidator = ToscaPropertyType.INTEGER.getValidator(); + break; + case FLOAT: + innerValidator = ToscaPropertyType.FLOAT.getValidator(); + break; + case BOOLEAN: + innerValidator = ToscaPropertyType.BOOLEAN.getValidator(); + break; + case JSON: + innerValidator = ToscaPropertyType.JSON.getValidator(); + break; + default: + log.debug("inner Tosca Type is unknown: {}", innerToscaType); + return false; + } + + } else { + log.debug("inner Tosca Type is: {}", innerType); + + boolean isValid = validateComplexInnerType(value, innerType, allDataTypes); + log.debug("Finish to validate value {} of map with inner type {}. Result is {}", value, innerType, isValid); + return isValid; + + } + + try { + JsonElement jsonObject = jsonParser.parse(value); + JsonObject asJsonObject = jsonObject.getAsJsonObject(); + Set> entrySet = asJsonObject.entrySet(); + for (Entry entry : entrySet) { + String currentKey = entry.getKey(); + JsonElement jsonValue = entry.getValue(); + + String element = JsonUtils.toString(jsonValue); + + if (!innerValidator.isValid(element, null, allDataTypes) + || !keyValidator.isValid(entry.getKey(), null, allDataTypes)) { + log.debug("validation of key : {}, element: {} failed", currentKey, entry.getValue()); + return false; + } + } + + return true; + } catch (JsonSyntaxException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Map Validator"); + } + + return false; + + } + + private boolean validateComplexInnerType(String value, String innerType, + Map allDataTypes) { + + DataTypeDefinition innerDataTypeDefinition = allDataTypes.get(innerType); + if (innerDataTypeDefinition == null) { + log.debug("Data type {} cannot be found in our data types.", innerType); + return false; + } + + try { + JsonElement jsonObject = jsonParser.parse(value); + JsonObject asJsonObject = jsonObject.getAsJsonObject(); + Set> entrySet = asJsonObject.entrySet(); + for (Entry entry : entrySet) { + String currentKey = entry.getKey(); + JsonElement currentValue = entry.getValue(); + + if (currentValue != null) { + String element = JsonUtils.toString(currentValue); + boolean isValid = dataTypeValidatorConverter.isValid(element, innerDataTypeDefinition, + allDataTypes); + if (isValid == false) { + log.debug("Cannot parse value {} from type {} of key {}", currentValue, innerType, currentKey); + return false; + } + } + } + + } catch (Exception e) { + log.debug("Cannot parse value {} of map from inner type {}. {}", value, innerType, e); + return false; + } + + return true; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java new file mode 100644 index 0000000000..35862148f9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.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.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public interface PropertyTypeValidator { + + boolean isValid(String value, String innerType, Map allDataTypes); + + boolean isValid(String value, String innerType); + /* + * The value format should be validated according to the “Property Type�? : + * “integer�? - valid tag:yaml.org,2002:int , the number base 8,10,18 should + * be handled ( hint : to validate by calling parseInt( + * s,10)/parseInt(s,16)/parseInt(s,8) or just regexp [-+]?[0-9]+ for Base 10 + * , [-+]?0[0-7]+ for Base 8 , [-+]?0x[0-9a-fA-F]+ for Base 16 + * + * “float�? - valid tag:yaml.org,2002:float , parseFloat() “boolean�? - valid + * tag:yaml.org,2002:bool : can be only “true�? or “false�? ( upper case + * characters should be converted to lower case : TRUE ->true, True->true + * “string�? - valid tag:yaml.org,2002:str and limited to 100 chars. + * + */ + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java new file mode 100644 index 0000000000..06994505a9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.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.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.Configuration.ToscaValidatorsConfig; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StringValidator implements PropertyTypeValidator { + + public static final int DEFAULT_STRING_MAXIMUM_LENGTH = 100; + + public static int STRING_MAXIMUM_LENGTH = DEFAULT_STRING_MAXIMUM_LENGTH; + + private static Logger log = LoggerFactory.getLogger(StringValidator.class.getName()); + + private static StringValidator stringValidator = new StringValidator(); + + public static StringValidator getInstance() { + return stringValidator; + } + + private StringValidator() { + if (ConfigurationManager.getConfigurationManager() != null) { + ToscaValidatorsConfig toscaValidators = ConfigurationManager.getConfigurationManager().getConfiguration() + .getToscaValidators(); + log.debug("toscaValidators={}", toscaValidators); + if (toscaValidators != null) { + Integer stringMaxLength = toscaValidators.getStringMaxLength(); + if (stringMaxLength != null) { + STRING_MAXIMUM_LENGTH = stringMaxLength; + } + } + } + } + + @Override + public boolean isValid(String value, String innerType, Map allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + if (value.length() > STRING_MAXIMUM_LENGTH) { + log.debug("parameter String length {} is higher the configured({})", value.length(), STRING_MAXIMUM_LENGTH); + return false; + } + String coverted = ValidationUtils.removeNoneUtf8Chars(value); + boolean isValid = ValidationUtils.validateIsAscii(coverted); + + if (false == isValid) { + log.debug("parameter String value {} is not ascii string.", (value != null ? value.substring(0, Math.min(value.length(), 20)) : null)); + } + + return isValid; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java new file mode 100644 index 0000000000..7f8dff42d0 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.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.be.model.tosca.validators; + +import java.util.Arrays; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaBooleanValidator implements PropertyTypeValidator { + + private static ToscaBooleanValidator booleanValidator = new ToscaBooleanValidator(); + + private static String[] validValues = { "true", "on", "yes", "y", "false", "off", "no", "n" }; + + public static ToscaBooleanValidator getInstance() { + return booleanValidator; + } + + private ToscaBooleanValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map dataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + return (Arrays.stream(validValues).filter(str -> str.equalsIgnoreCase(value)).toArray().length == 1); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java new file mode 100644 index 0000000000..dadfd49831 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.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.model.tosca.version; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.TechnicalException; + +public class ApplicationVersionException extends TechnicalException { + + private static final long serialVersionUID = -5192834855057177252L; + + public ApplicationVersionException(String message, Throwable cause) { + super(message, cause); + } + + public ApplicationVersionException(String message) { + super(message); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java new file mode 100644 index 0000000000..905d8bf3bc --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java @@ -0,0 +1,463 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.version; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Locale; +import java.util.Properties; +import java.util.Stack; + +/** + * Generic implementation of version comparison. + * + *

+ * Features: + *

    + *
  • mixing of '-' (dash) and '.' (dot) + * separators,
  • + *
  • transition between characters and digits also constitutes a separator: + * 1.0alpha1 => [1, 0, alpha, 1]
  • + *
  • unlimited number of version components,
  • + *
  • version components in the text can be digits or strings,
  • + *
  • strings are checked for well-known qualifiers and the qualifier ordering + * is used for version ordering. Well-known qualifiers (case insensitive) are: + *
      + *
    • alpha or a
    • + *
    • beta or b
    • + *
    • milestone or m
    • + *
    • rc or cr
    • + *
    • snapshot
    • + *
    • (the empty string) or ga or + * final
    • + *
    • sp
    • + *
    + * Unknown qualifiers are considered after known qualifiers, with lexical order + * (always case insensitive),
  • + *
  • a dash usually precedes a qualifier, and is always less important than + * something preceded with a dot.
  • + *
+ *

+ * + * @see "Versioning" + * on Maven Wiki + * @author Kenney Westerhof + * @author Hervé Boutemy + */ +public class ComparableVersion implements Comparable { + private String value; + + private String canonical; + + private ListItem items; + + private interface Item { + int INTEGER_ITEM = 0; + int STRING_ITEM = 1; + int LIST_ITEM = 2; + + int compareTo(Item item); + + int getType(); + + boolean isNull(); + } + + /** + * Represents a numeric item in the version item list. + */ + private static class IntegerItem implements Item { + private static final BigInteger BIG_INTEGER_ZERO = new BigInteger("0"); + + private final BigInteger value; + + public static final IntegerItem ZERO = new IntegerItem(); + + private IntegerItem() { + this.value = BIG_INTEGER_ZERO; + } + + public IntegerItem(String str) { + this.value = new BigInteger(str); + } + + @Override + public int getType() { + return INTEGER_ITEM; + } + + @Override + public boolean isNull() { + return BIG_INTEGER_ZERO.equals(value); + } + + @Override + public int compareTo(Item item) { + if (item == null) { + return BIG_INTEGER_ZERO.equals(value) ? 0 : 1; // 1.0 == 1, 1.1 + // > 1 + } + + switch (item.getType()) { + case INTEGER_ITEM: + return value.compareTo(((IntegerItem) item).value); + + case STRING_ITEM: + return 1; // 1.1 > 1-sp + + case LIST_ITEM: + return 1; // 1.1 > 1-1 + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + @Override + public String toString() { + return value.toString(); + } + } + + /** + * Represents a string in the version item list, usually a qualifier. + */ + private static class StringItem implements Item { + private static final String[] QUALIFIERS = { "alpha", "beta", "milestone", "rc", "snapshot", "", "sp" }; + + private static final List _QUALIFIERS = Arrays.asList(QUALIFIERS); + + private static final Properties ALIASES = new Properties(); + static { + ALIASES.put("ga", ""); + ALIASES.put("final", ""); + ALIASES.put("cr", "rc"); + } + + /** + * A comparable value for the empty-string qualifier. This one is used + * to determine if a given qualifier makes the version older than one + * without a qualifier, or more recent. + */ + private static final String RELEASE_VERSION_INDEX = String.valueOf(_QUALIFIERS.indexOf("")); + + private String value; + + public StringItem(String value, boolean followedByDigit) { + if (followedByDigit && value.length() == 1) { + // a1 = alpha-1, b1 = beta-1, m1 = milestone-1 + switch (value.charAt(0)) { + case 'a': + value = "alpha"; + break; + case 'b': + value = "beta"; + break; + case 'm': + value = "milestone"; + break; + } + } + this.value = ALIASES.getProperty(value, value); + } + + @Override + public int getType() { + return STRING_ITEM; + } + + @Override + public boolean isNull() { + return (comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX) == 0); + } + + /** + * Returns a comparable value for a qualifier. + * + * This method takes into account the ordering of known qualifiers then + * unknown qualifiers with lexical ordering. + * + * just returning an Integer with the index here is faster, but requires + * a lot of if/then/else to check for -1 or QUALIFIERS.size and then + * resort to lexical ordering. Most comparisons are decided by the first + * character, so this is still fast. If more characters are needed then + * it requires a lexical sort anyway. + * + * @param qualifier + * @return an equivalent value that can be used with lexical comparison + */ + public static String comparableQualifier(String qualifier) { + int i = _QUALIFIERS.indexOf(qualifier); + + return i == -1 ? (_QUALIFIERS.size() + "-" + qualifier) : String.valueOf(i); + } + + // @Override + public int compareTo(Item item) { + if (item == null) { + // 1-rc < 1, 1-ga > 1 + return comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX); + } + switch (item.getType()) { + case INTEGER_ITEM: + return -1; // 1.any < 1.1 ? + + case STRING_ITEM: + return comparableQualifier(value).compareTo(comparableQualifier(((StringItem) item).value)); + + case LIST_ITEM: + return -1; // 1.any < 1-1 + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + @Override + public String toString() { + return value; + } + } + + /** + * Represents a version list item. This class is used both for the global + * item list and for sub-lists (which start with '-(number)' in the version + * specification). + */ + private static class ListItem extends ArrayList implements Item { + + private static final long serialVersionUID = -4740226741001149657L; + + @Override + public int getType() { + return LIST_ITEM; + } + + @Override + public boolean isNull() { + return (size() == 0); + } + + void normalize() { + for (ListIterator iterator = listIterator(size()); iterator.hasPrevious();) { + Item item = iterator.previous(); + if (item.isNull()) { + iterator.remove(); // remove null trailing items: 0, "", + // empty list + } else { + break; + } + } + } + + @Override + public int compareTo(Item item) { + if (item == null) { + if (size() == 0) { + return 0; // 1-0 = 1- (normalize) = 1 + } + Item first = get(0); + return first.compareTo(null); + } + switch (item.getType()) { + case INTEGER_ITEM: + return -1; // 1-1 < 1.0.x + + case STRING_ITEM: + return 1; // 1-1 > 1-sp + + case LIST_ITEM: + Iterator left = iterator(); + Iterator right = ((ListItem) item).iterator(); + + while (left.hasNext() || right.hasNext()) { + Item l = left.hasNext() ? left.next() : null; + Item r = right.hasNext() ? right.next() : null; + + int result = 0; + if (r != null && l != null) { + result = l.compareTo(r); + } else if (r == null && l == null) { + result = 0; + } else if (l == null) { + result = -1; + } else { + result = 1; + } + + // if this is shorter, then invert the compare and mul with + // -1 + // int result = (l == null ? (r == null ? 0 : -1 * + // r.compareTo(l)) : l.compareTo(r)); + + if (result != 0) { + return result; + } + } + + return 0; + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder("("); + for (Iterator iter = iterator(); iter.hasNext();) { + buffer.append(iter.next()); + if (iter.hasNext()) { + buffer.append(','); + } + } + buffer.append(')'); + return buffer.toString(); + } + } + + public ComparableVersion(String version) { + parseVersion(version); + } + + public final void parseVersion(String version) { + this.value = version; + + items = new ListItem(); + + version = version.toLowerCase(Locale.ENGLISH); + + ListItem list = items; + + Stack stack = new Stack(); + stack.push(list); + + boolean isDigit = false; + + int startIndex = 0; + + for (int i = 0; i < version.length(); i++) { + char c = version.charAt(i); + + if (c == '.') { + if (i == startIndex) { + list.add(IntegerItem.ZERO); + } else { + list.add(parseItem(isDigit, version.substring(startIndex, i))); + } + startIndex = i + 1; + } else if (c == '-') { + if (i == startIndex) { + list.add(IntegerItem.ZERO); + } else { + list.add(parseItem(isDigit, version.substring(startIndex, i))); + } + startIndex = i + 1; + + if (isDigit) { + list.normalize(); // 1.0-* = 1-* + + if ((i + 1 < version.length()) && Character.isDigit(version.charAt(i + 1))) { + // new ListItem only if previous were digits and new + // char is a digit, + // ie need to differentiate only 1.1 from 1-1 + list.add(list = new ListItem()); + + stack.push(list); + } + } + } else if (Character.isDigit(c)) { + if (!isDigit && i > startIndex) { + list.add(new StringItem(version.substring(startIndex, i), true)); + startIndex = i; + } + + isDigit = true; + } else { + if (isDigit && i > startIndex) { + list.add(parseItem(true, version.substring(startIndex, i))); + startIndex = i; + } + + isDigit = false; + } + } + + if (version.length() > startIndex) { + list.add(parseItem(isDigit, version.substring(startIndex))); + } + + while (!stack.isEmpty()) { + list = (ListItem) stack.pop(); + list.normalize(); + } + + canonical = items.toString(); + } + + private static Item parseItem(boolean isDigit, String buf) { + return isDigit ? new IntegerItem(buf) : new StringItem(buf, false); + } + + @Override + public int compareTo(ComparableVersion o) { + return items.compareTo(o.items); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object o) { + return (o instanceof ComparableVersion) && canonical.equals(((ComparableVersion) o).canonical); + } + + @Override + public int hashCode() { + return canonical.hashCode(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java new file mode 100644 index 0000000000..268ee28b96 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java @@ -0,0 +1,192 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.tosca.version; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.StringTokenizer; +import java.util.regex.Pattern; + +/** + * Default implementation of artifact versioning. + * + * @author Brett Porter + */ +public class Version implements Comparable { + private Integer majorVersion; + + private Integer minorVersion; + + private Integer incrementalVersion; + + private Integer buildNumber; + + private String qualifier; + + private ComparableVersion comparable; + + public Version(String version) { + parseVersion(version); + } + + @Override + public int hashCode() { + return 11 + comparable.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (!(other instanceof Version)) { + return false; + } + + return compareTo((Version) other) == 0; + } + + public int compareTo(Version otherVersion) { + return this.comparable.compareTo(otherVersion.comparable); + } + + public int getMajorVersion() { + return majorVersion != null ? majorVersion : 0; + } + + public int getMinorVersion() { + return minorVersion != null ? minorVersion : 0; + } + + public int getIncrementalVersion() { + return incrementalVersion != null ? incrementalVersion : 0; + } + + public int getBuildNumber() { + return buildNumber != null ? buildNumber : 0; + } + + public String getQualifier() { + return qualifier; + } + + public final void parseVersion(String version) { + comparable = new ComparableVersion(version); + + int index = version.indexOf("-"); + + String part1; + String part2 = null; + + if (index < 0) { + part1 = version; + } else { + part1 = version.substring(0, index); + part2 = version.substring(index + 1); + } + + if (part2 != null) { + try { + if ((part2.length() == 1) || !part2.startsWith("0")) { + buildNumber = Integer.valueOf(part2); + } else { + qualifier = part2; + } + } catch (NumberFormatException e) { + qualifier = part2; + } + } + + if ((!part1.contains(".")) && !part1.startsWith("0")) { + try { + majorVersion = Integer.valueOf(part1); + } catch (NumberFormatException e) { + // qualifier is the whole version, including "-" + qualifier = version; + buildNumber = null; + } + } else { + boolean fallback = false; + + StringTokenizer tok = new StringTokenizer(part1, "."); + try { + majorVersion = getNextIntegerToken(tok); + if (tok.hasMoreTokens()) { + minorVersion = getNextIntegerToken(tok); + } + if (tok.hasMoreTokens()) { + incrementalVersion = getNextIntegerToken(tok); + } + if (tok.hasMoreTokens()) { + qualifier = tok.nextToken(); + fallback = Pattern.compile("\\d+").matcher(qualifier).matches(); + } + + // string tokenzier won't detect these and ignores them + if (part1.contains("..") || part1.startsWith(".") || part1.endsWith(".")) { + fallback = true; + } + } catch (NumberFormatException e) { + fallback = true; + } + + if (fallback) { + // qualifier is the whole version, including "-" + qualifier = version; + majorVersion = null; + minorVersion = null; + incrementalVersion = null; + buildNumber = null; + } + } + } + + private static Integer getNextIntegerToken(StringTokenizer tok) { + String s = tok.nextToken(); + if ((s.length() > 1) && s.startsWith("0")) { + throw new NumberFormatException("Number part has a leading 0: '" + s + "'"); + } + return Integer.valueOf(s); + } + + @Override + public String toString() { + return comparable.toString(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java new file mode 100644 index 0000000000..f95a89db62 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.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.be.unittests.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +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.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.RequirementData; + +public final class FactoryUtils { + private FactoryUtils() { + }; + + public static final class Constants { + public static final String DEFAULT_CAPABILITY_TYPE = "tosca.capabilities.Node"; + } + + public static Resource createVFWithRI(String riVersion) { + Resource vf = createVF(); + ComponentInstance ri = createResourceInstanceWithVersion(riVersion); + addComponentInstanceToVF(vf, ri); + return vf; + } + + public static Resource createVF() { + Resource resource = new Resource(); + String uniqueId = UUID.randomUUID().toString(); + resource.setUniqueId(uniqueId); + return resource; + } + + public static void addComponentInstanceToVF(Resource vf, ComponentInstance resourceInstance) { + List componentsInstances = vf.getComponentInstances() != null ? vf.getComponentInstances() + : new ArrayList<>(); + componentsInstances.add(resourceInstance); + vf.setComponentInstances(componentsInstances); + } + + public static ComponentInstance createResourceInstance() { + ComponentInstance ri = new ComponentInstance(); + ri.setComponentVersion("0.1"); + String uniqueId = UUID.randomUUID().toString(); + ri.setComponentUid(uniqueId); + ri.setUniqueId(uniqueId); + ri.setName("genericRI" + uniqueId); + ri.setOriginType(OriginTypeEnum.VF); + return ri; + + } + + public static ComponentInstance createResourceInstanceWithVersion(String riVersion) { + ComponentInstance ri = createResourceInstance(); + ri.setComponentVersion(riVersion); + return ri; + } + + public static CapabilityData createCapabilityData() { + CapabilityData capData = new CapabilityData(); + String uniqueId = UUID.randomUUID().toString(); + capData.setUniqueId(uniqueId); + + capData.setType(Constants.DEFAULT_CAPABILITY_TYPE); + return capData; + } + + public static RequirementData createRequirementData() { + RequirementData reqData = new RequirementData(); + String uniqueId = UUID.randomUUID().toString(); + reqData.setUniqueId(uniqueId); + return reqData; + } + + public static CapabilityDefinition convertCapabilityDataToCapabilityDefinitionAddProperties( + CapabilityData capData) { + CapabilityDefinition capDef = new CapabilityDefinition(); + capDef.setName("Cap2"); + capDef.setDescription(capData.getDescription()); + capDef.setUniqueId(capData.getUniqueId()); + capDef.setValidSourceTypes(capData.getValidSourceTypes()); + capDef.setType(capData.getType()); + capDef.setProperties(new ArrayList<>()); + ComponentInstanceProperty host = new ComponentInstanceProperty(); + host.setUniqueId(UUID.randomUUID().toString()); + host.setName("host"); + host.setDefaultValue("defhost"); + host.setType("string"); + + host.setSchema(new SchemaDefinition()); + host.getSchema().setProperty(new PropertyDataDefinition()); + host.getSchema().getProperty().setType("string"); + + capDef.getProperties().add(host); + ComponentInstanceProperty port = new ComponentInstanceProperty(); + port.setName("port"); + port.setDefaultValue("defport"); + port.setUniqueId(UUID.randomUUID().toString()); + port.setType("string"); + + port.setSchema(new SchemaDefinition()); + port.getSchema().setProperty(new PropertyDataDefinition()); + port.getSchema().getProperty().setType("string"); + + capDef.getProperties().add(port); + return capDef; + } + + public static List createComponentInstancePropertyList() { + List properties = new ArrayList<>(); + ComponentInstanceProperty host = new ComponentInstanceProperty(); + host.setUniqueId(UUID.randomUUID().toString()); + host.setName("host"); + host.setValue("newhost"); + host.setType("string"); + + host.setSchema(new SchemaDefinition()); + host.getSchema().setProperty(new PropertyDataDefinition()); + host.getSchema().getProperty().setType("string"); + + properties.add(host); + ComponentInstanceProperty port = new ComponentInstanceProperty(); + port.setName("port"); + port.setValue("newport"); + port.setUniqueId(UUID.randomUUID().toString()); + port.setType("string"); + + port.setSchema(new SchemaDefinition()); + port.getSchema().setProperty(new PropertyDataDefinition()); + port.getSchema().getProperty().setType("string"); + + properties.add(port); + return properties; + } + + public static RequirementDefinition convertRequirementDataIDToRequirementDefinition(String reqDataId) { + RequirementDefinition reqDef = new RequirementDefinition(); + reqDef.setUniqueId(reqDataId); + reqDef.setCapability(Constants.DEFAULT_CAPABILITY_TYPE); + return reqDef; + } + + public static GraphEdge createGraphEdge() { + GraphEdge graphEdge = new GraphEdge(); + return graphEdge; + } + + public static CapabilityInstData createCapabilityInstData() { + CapabilityInstData capInstData = new CapabilityInstData(); + String uniqueId = UUID.randomUUID().toString(); + capInstData.setUniqueId(uniqueId); + return capInstData; + } + + public static PropertyValueData createPropertyData() { + PropertyValueData propData = new PropertyValueData(); + String uniqueId = UUID.randomUUID().toString(); + propData.setValue("localhost"); + propData.setUniqueId(uniqueId); + return propData; + } + + public static PropertyData convertCapabilityDefinitionToCapabilityData(PropertyDefinition propDef) { + PropertyData propData = new PropertyData(); + propData.getPropertyDataDefinition().setUniqueId(propDef.getUniqueId()); + propData.getPropertyDataDefinition().setDefaultValue(propDef.getDefaultValue()); + return propData; + } + + public static CapabilityDefinition convertCapabilityDataToCapabilityDefinitionRoot(CapabilityData capData) { + CapabilityDefinition capDef = new CapabilityDefinition(); + capDef.setName("Cap1"); + capDef.setDescription(capData.getDescription()); + capDef.setUniqueId(capData.getUniqueId()); + capDef.setValidSourceTypes(capData.getValidSourceTypes()); + capDef.setType(capData.getType()); + capDef.setProperties(new ArrayList<>()); + ComponentInstanceProperty host = new ComponentInstanceProperty(); + host.setUniqueId(UUID.randomUUID().toString()); + host.setName("host"); + host.setDefaultValue("roothost"); + host.setType("string"); + + host.setSchema(new SchemaDefinition()); + host.getSchema().setProperty(new PropertyDataDefinition()); + host.getSchema().getProperty().setType("string"); + + capDef.getProperties().add(host); + ComponentInstanceProperty port = new ComponentInstanceProperty(); + port.setName("port"); + port.setDefaultValue("rootport"); + port.setUniqueId(UUID.randomUUID().toString()); + port.setType("string"); + + port.setSchema(new SchemaDefinition()); + port.getSchema().setProperty(new PropertyDataDefinition()); + port.getSchema().getProperty().setType("string"); + + capDef.getProperties().add(port); + return capDef; + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ModelTestBase.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ModelTestBase.java new file mode 100644 index 0000000000..f18aa61b74 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ModelTestBase.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.model; + +import org.openecomp.sdc.be.config.Configuration; +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; + +public class ModelTestBase { + + protected static ConfigurationManager configurationManager; + + public static void init() { + if (ConfigurationManager.getConfigurationManager() == null) { + String appConfigDir = "src/test/resources/config"; + ConfigurationSource configurationSource = new FSConfigurationSource( + ExternalConfiguration.getChangeListener(), appConfigDir); + configurationManager = new ConfigurationManager(configurationSource); + + Configuration configuration = new Configuration(); + configuration.setTitanInMemoryGraph(true); + + configurationManager.setConfiguration(configuration); + } + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/JsonObjectTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/JsonObjectTest.java new file mode 100644 index 0000000000..dd102e7ed5 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/JsonObjectTest.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.model.operations; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.ArrayList; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.UploadArtifactInfo; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonObjectTest { + + private ObjectMapper mapper; + UploadResourceInfo inputObjectRef; + private final String INPUT_RESOURCE_STRING = "{ \"payloadData\" : \"My Test Object\", \"payloadName\" : \"TestName\", " + + " \"description\":\"my_description\",\"tags\":[\"tag1\"], " + + "\"artifactList\" : [ { \"artifactName\" : \"myArtifact0\", \"artifactPath\" : \"scripts/\", \"artifactType\" : \"PUPPET\", " + + " \"artifactDescription\" : \"This is Description\", \"artifactData\" : null }, " + + "{ \"artifactName\" : \"myArtifact1\", \"artifactPath\" : \"scripts/\", \"artifactType\" : \"PUPPET\", \"artifactDescription\" : \"This is Description\", " + + " \"artifactData\" : null } ], \"contactId\" : null, \"name\" : null, \"resourceIconPath\" : null, \"vendorName\" : null, \"vendorRelease\" : null , \"resourceType\" : \"VFC\" }"; + + @Before + public void setup() { + mapper = new ObjectMapper(); + ArrayList artifactList = new ArrayList(); + for (int i = 0; i < 2; i++) { + UploadArtifactInfo artifactInfo = new UploadArtifactInfo("myArtifact" + i, "scripts/", + ArtifactTypeEnum.PUPPET, "This is Description"); + artifactList.add(artifactInfo); + } + ArrayList tags = new ArrayList<>(); + tags.add("tag1"); + inputObjectRef = new UploadResourceInfo("My Test Object", "TestName", "my_description", null, tags, + artifactList); + + } + + @Test + public void testStringToUploadResourceInfo() throws JsonParseException, JsonMappingException, IOException { + UploadResourceInfo resourceObjectTest = mapper.readValue(INPUT_RESOURCE_STRING, UploadResourceInfo.class); + assertEquals(inputObjectRef, resourceObjectTest); + + } + + // @Test + public void testUploadResourceInfoToString() throws JsonParseException, JsonMappingException, IOException { + String refAsString = mapper.writeValueAsString(inputObjectRef); + String unFormattedString = refAsString.replace("\n", "").replace("\t", "").replace(" ", ""); + + assertEquals(unFormattedString, INPUT_RESOURCE_STRING.replace("\n", "").replace("\t", "").replace(" ", "")); + + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperationTest.java new file mode 100644 index 0000000000..3e871f1fa0 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperationTest.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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +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.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Point; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +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.impl.util.OperationTestsUtil; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.exception.DeleteReferencedObjectException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thinkaurelius.titan.core.TitanGraph; +//import com.tinkerpop.blueprints.Vertex; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class AdditionalInformationOperationTest extends ModelTestBase { + + private Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + + private static String USER_ID = "muuserid"; + private static String CATEGORY_NAME = "category/mycategory"; + + @javax.annotation.Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + @javax.annotation.Resource(name = "resource-operation") + private ResourceOperation resourceOperation; + + @javax.annotation.Resource(name = "additional-information-operation") + private IAdditionalInformationOperation additionalInformationOperation; + + @Before + public void createUserAndCategory() { + deleteAndCreateCategory(CATEGORY_NAME); + deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID); + + } + + @BeforeClass + public static void setupBeforeClass() { + + ModelTestBase.init(); + + } + + @Test + public void testDummy() { + + assertTrue(additionalInformationOperation != null); + + } + + private int getNumberOfVerticesOnGraph() { + Either graphResult = titanDao.getGraph(); + TitanGraph graph = graphResult.left().value(); + + int i = 0; + Iterable vertices = graph.query().vertices(); + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + i++; + } + + } + + titanDao.commit(); + + return i; + } + + @Test + public void testCreateAndDeleteResource() { + + int before = getNumberOfVerticesOnGraph(); + + Resource newResource = createResource(USER_ID, CATEGORY_NAME, "testCreateAndDeleteResource", "0.1", null, false, + true); + String resourceId = newResource.getUniqueId(); + + Either deleteResource = resourceOperation.deleteResource(resourceId); + assertTrue(deleteResource.isLeft()); + + int after = getNumberOfVerticesOnGraph(); + + assertEquals("check number of vertices not changed", before, after); + } + + private Resource buildResourceMetadata(String userId, String category, String resourceName, + String resourceVersion) { + + Resource resource = new Resource(); + resource.setName(resourceName); + resource.setVersion(resourceVersion); + ; + resource.setDescription("description 1"); + resource.setAbstract(false); + resource.setCreatorUserId(userId); + resource.setContactId("contactId@sdc.com"); + resource.setVendorName("vendor 1"); + resource.setVendorRelease("1.0.0"); + String[] categoryArr = category.split("/"); + resource.addCategory(categoryArr[0], categoryArr[1]); + resource.setIcon("images/my.png"); + // List tags = new ArrayList(); + // tags.add("TAG1"); + // tags.add("TAG2"); + // resource.setTags(tags); + return resource; + } + + private UserData deleteAndCreateUser(String userId, String firstName, String lastName) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + + titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanDao.createNode(userData, UserData.class); + titanDao.commit(); + + return userData; + } + + private void deleteAndCreateCategory(String category) { + String[] names = category.split("/"); + OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao); + } + + public Resource createResource(String userId, String category, String resourceName, String resourceVersion, + String parentResourceName, boolean isAbstract, boolean isHighestVersion) { + + List derivedFrom = new ArrayList(); + if (parentResourceName != null) { + derivedFrom.add(parentResourceName); + } + Resource resource = buildResourceMetadata(userId, category, resourceName, resourceVersion); + + resource.setAbstract(isAbstract); + resource.setHighestVersion(isHighestVersion); + + Either result = resourceOperation.createResource(resource, true); + + assertTrue(result.isLeft()); + Resource resultResource = result.left().value(); + + assertEquals("check resource state", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + resultResource.getLifecycleState()); + + return resultResource; + + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperationTest.java new file mode 100644 index 0000000000..0143e50dc7 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperationTest.java @@ -0,0 +1,574 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary; +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.ArtifactDefinition; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +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.util.OperationTestsUtil; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.HeatParameterData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class ArtifactOperationTest extends ModelTestBase { + + private static final String ARTIFACT_NAME = "myHeatArtifact"; + + @javax.annotation.Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + @javax.annotation.Resource(name = "service-operation") + private ServiceOperation serviceOperation; + + @javax.annotation.Resource + private IGraphLockOperation graphLockOperation; + + @javax.annotation.Resource + private ArtifactOperation artifactOperation; + + @javax.annotation.Resource(name = "requirement-operation") + private RequirementOperation requirementOperation; + + @javax.annotation.Resource(name = "resource-operation") + private ResourceOperation resourceOperation; + + @javax.annotation.Resource(name = "property-operation") + private PropertyOperation propertyOperation; + + @javax.annotation.Resource(name = "capability-operation") + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource(name = "capability-type-operation") + private CapabilityTypeOperation capabilityTypeOperation; + + @javax.annotation.Resource(name = "component-instance-operation") + private ComponentInstanceOperation resourceInstanceOperation; + + @javax.annotation.Resource(name = "lifecycle-operation") + private LifecycleOperation lifecycleOperation; + + private static Logger log = LoggerFactory.getLogger(ServiceOperation.class.getName()); + + private static String RESOURCE_ID = "resourceId"; + private static String RESOURCE_ID_2 = "resourceId2"; + + private static String USER_ID = "muserid"; + private static String CATEGORY_NAME = "category/mycategory"; + + @BeforeClass + public static void setupBeforeClass() { + + ModelTestBase.init(); + } + + @Before + public void createUserAndCategory() { + deleteAndCreateCategory(CATEGORY_NAME); + deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID, null); + } + +// @Test + public void testAddArtifactToServiceVersionAndUUIDNotNull() { + CategoryDefinition category = new CategoryDefinition(); + category.setName(CATEGORY_NAME); + + String serviceName = "servceTest2"; + String serviceVersion = "0.1"; + String userId = USER_ID; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug("{}", serviceAfterSave); + String serviceId = serviceAfterSave.getUniqueId(); + + ArtifactDefinition artifactInfo = addArtifactToService(userId, serviceId, "install_apache"); + + assertEquals("add informational artifact version : " + artifactInfo.getArtifactVersion(), "1", + artifactInfo.getArtifactVersion()); + + assertNotNull("add informational artifact version : " + artifactInfo.getArtifactUUID(), + artifactInfo.getArtifactUUID()); + + Either service = serviceOperation.getService(serviceId); + assertTrue(service.isLeft()); + + Map artifacts = service.left().value().getArtifacts(); + for (Map.Entry entry : artifacts.entrySet()) { + String artifactId = entry.getValue().getUniqueId(); + String description = entry.getValue().getDescription(); + + artifactOperation.removeArifactFromResource(serviceId, artifactId, NodeTypeEnum.Service, true, false); + } + service = serviceOperation.getService(serviceId); + assertTrue(service.isLeft()); + + artifacts = service.left().value().getArtifacts(); + assertEquals(0, artifacts.size()); + + Either serviceDelete = serviceOperation.deleteService(serviceId); + + Either, TitanOperationStatus> byCriteria = titanDao.getByCriteria(NodeTypeEnum.ArtifactRef, + null, ArtifactData.class); + assertTrue(byCriteria.isRight()); + assertEquals(TitanOperationStatus.NOT_FOUND, byCriteria.right().value()); + + serviceOperation.deleteService(serviceAfterSave.getUniqueId()); + + } + +// @Test + public void testUpdateArtifactToServiceVersionNotChanged() { + CategoryDefinition category = new CategoryDefinition(); + category.setName(CATEGORY_NAME); + String serviceName = "servceTest2"; + String serviceVersion = "0.1"; + String userId = USER_ID; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug("{}", serviceAfterSave); + String serviceId = serviceAfterSave.getUniqueId(); + + ArtifactDefinition artifactInfo = addArtifactToService(userId, serviceId, "install_apache"); + + String version = artifactInfo.getArtifactVersion(); + String artUuid = artifactInfo.getArtifactUUID(); + assertEquals("add informational artifact version : " + version, "1", version); + + artifactInfo.setDescription("jghlsk new desfnjdh"); + + Either artifact = artifactOperation.updateArifactOnResource( + artifactInfo, serviceId, artifactInfo.getUniqueId(), NodeTypeEnum.Service, false); + String newVersion = artifact.left().value().getArtifactVersion(); + String newArtUuid = artifactInfo.getArtifactUUID(); + assertEquals("add informational artifact version : " + newVersion, newVersion, version); + assertEquals("add informational artifact uuid : " + newArtUuid, newArtUuid, artUuid); + + Either service = serviceOperation.getService(serviceId); + assertTrue(service.isLeft()); + + Map artifacts = service.left().value().getArtifacts(); + for (Map.Entry entry : artifacts.entrySet()) { + String artifactId = entry.getValue().getUniqueId(); + String description = entry.getValue().getDescription(); + + artifactOperation.removeArifactFromResource(serviceId, artifactId, NodeTypeEnum.Service, true, false); + } + service = serviceOperation.getService(serviceId); + assertTrue(service.isLeft()); + + artifacts = service.left().value().getArtifacts(); + assertEquals(0, artifacts.size()); + + Either serviceDelete = serviceOperation.deleteService(serviceId); + + Either, TitanOperationStatus> byCriteria = titanDao.getByCriteria(NodeTypeEnum.ArtifactRef, + null, ArtifactData.class); + assertTrue(byCriteria.isRight()); + assertEquals(TitanOperationStatus.NOT_FOUND, byCriteria.right().value()); + + serviceOperation.deleteService(serviceAfterSave.getUniqueId()); + + } + + @Test + public void testCreateDeleteArtifactWithHeatParams() { + + ArtifactDefinition artifactWithHeat = createResourceWithHeat(); + + List heatParameters = artifactWithHeat.getHeatParameters(); + assertNotNull(heatParameters); + assertTrue(heatParameters.size() == 1); + HeatParameterDefinition parameter = heatParameters.get(0); + HeatParameterData parameterData = new HeatParameterData(parameter); + Either parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), + parameterData.getUniqueId(), HeatParameterData.class); + assertTrue(parameterNode.isLeft()); + + Either removeArifact = artifactOperation.removeArifactFromResource( + RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, true, false); + assertTrue(removeArifact.isLeft()); + + ArtifactData artifactData = new ArtifactData(artifactWithHeat); + Either artifactAfterDelete = titanDao.getNode(artifactData.getUniqueIdKey(), + artifactData.getUniqueId(), ArtifactData.class); + assertTrue(artifactAfterDelete.isRight()); + + Either parameterNodeAfterDelete = titanDao + .getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class); + assertTrue(parameterNodeAfterDelete.isRight()); + + titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class); + } + + @Test + public void testUpdateArtifactWithHeatParams() { + + ArtifactDefinition artifactWithHeat = createResourceWithHeat(); + + List heatParameters = artifactWithHeat.getHeatParameters(); + assertNotNull(heatParameters); + assertTrue(heatParameters.size() == 1); + HeatParameterDefinition parameter = heatParameters.get(0); + HeatParameterData parameterData = new HeatParameterData(parameter); + Either parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), + parameterData.getUniqueId(), HeatParameterData.class); + assertTrue(parameterNode.isLeft()); + + // update to artifact without params + ArtifactDefinition artifactNoParams = createArtifactDefinition(USER_ID, RESOURCE_ID, ARTIFACT_NAME); + artifactNoParams.setUniqueId(artifactWithHeat.getUniqueId()); + artifactNoParams.setArtifactType("HEAT"); + artifactNoParams.setArtifactVersion("2"); + artifactNoParams.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); + + Either updateArifact = artifactOperation.updateArifactOnResource( + artifactNoParams, RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, false); + assertTrue(updateArifact.isLeft()); + + ArtifactData artifactData = new ArtifactData(artifactWithHeat); + Either artifactAfterUpdate = titanDao.getNode(artifactData.getUniqueIdKey(), + artifactData.getUniqueId(), ArtifactData.class); + assertTrue(artifactAfterUpdate.isLeft()); + ArtifactData artifactAfterUpdateValue = artifactAfterUpdate.left().value(); + assertTrue(artifactNoParams.getArtifactVersion() + .equals(artifactAfterUpdateValue.getArtifactDataDefinition().getArtifactVersion())); + + Either parameterNodeAfterDelete = titanDao + .getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class); + assertTrue(parameterNodeAfterDelete.isRight()); + + artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, + true, false); + titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class); + titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class); + } + + @Test + public void testUpdateArtifactMetadataWithHeatParams() { + + ArtifactDefinition artifactWithHeat = createResourceWithHeat(); + + List heatParameters = artifactWithHeat.getHeatParameters(); + assertNotNull(heatParameters); + assertTrue(heatParameters.size() == 1); + HeatParameterDefinition parameter = heatParameters.get(0); + HeatParameterData parameterData = new HeatParameterData(parameter); + Either parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), + parameterData.getUniqueId(), HeatParameterData.class); + assertTrue(parameterNode.isLeft()); + + // update to artifact without params + artifactWithHeat.setArtifactVersion("2"); + artifactWithHeat.setArtifactChecksum(null); + artifactWithHeat.setPayloadData(null); + + Either updateArifact = artifactOperation.updateArifactOnResource( + artifactWithHeat, RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, false); + assertTrue(updateArifact.isLeft()); + + ArtifactData artifactData = new ArtifactData(artifactWithHeat); + Either artifactAfterUpdate = titanDao.getNode(artifactData.getUniqueIdKey(), + artifactData.getUniqueId(), ArtifactData.class); + assertTrue(artifactAfterUpdate.isLeft()); + ArtifactData artifactAfterUpdateValue = artifactAfterUpdate.left().value(); + assertTrue(artifactWithHeat.getArtifactVersion() + .equals(artifactAfterUpdateValue.getArtifactDataDefinition().getArtifactVersion())); + + Either parameterNodeAfterDelete = titanDao + .getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class); + assertTrue(parameterNodeAfterDelete.isLeft()); + + Either removeArifact = artifactOperation.removeArifactFromResource( + RESOURCE_ID_2, (String) artifactAfterUpdateValue.getUniqueId(), NodeTypeEnum.Resource, true, false); + removeArifact = artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), + NodeTypeEnum.Resource, true, false); + titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class); + titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class); + + } + + @Test + public void updateHeatArtifactWithTwoResources() { + ArtifactDefinition artifactWithHeat = createResourceWithHeat(); + + ResourceMetadataData resource2 = createResource(RESOURCE_ID_2); + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), ArtifactGroupTypeEnum.DEPLOYMENT.name()); + Either createRelation = titanDao.createRelation(resource2, + new ArtifactData(artifactWithHeat), GraphEdgeLabels.ARTIFACT_REF, props); + assertTrue(createRelation.isLeft()); + + List heatParameters = artifactWithHeat.getHeatParameters(); + assertNotNull(heatParameters); + assertTrue(heatParameters.size() == 1); + HeatParameterDefinition parameter = heatParameters.get(0); + HeatParameterData parameterData = new HeatParameterData(parameter); + Either parameterNode = titanDao.getNode(parameterData.getUniqueIdKey(), + parameterData.getUniqueId(), HeatParameterData.class); + assertTrue(parameterNode.isLeft()); + + ArtifactDefinition atifactToUpdate = new ArtifactDefinition(artifactWithHeat); + + // update to artifact without params + atifactToUpdate.setArtifactVersion("2"); + atifactToUpdate.setArtifactChecksum(null); + atifactToUpdate.setPayloadData(null); + + HeatParameterDefinition heatParamUpdate = new HeatParameterDefinition(parameter); + List heatParametersUpdated = new ArrayList(); + heatParamUpdate.setCurrentValue("55"); + heatParametersUpdated.add(heatParamUpdate); + atifactToUpdate.setHeatParameters(heatParametersUpdated); + + Either updateArifact = artifactOperation.updateArifactOnResource( + atifactToUpdate, RESOURCE_ID_2, atifactToUpdate.getUniqueId(), NodeTypeEnum.Resource, false); + assertTrue(updateArifact.isLeft()); + + // verify old artifact and parameter still exist + ArtifactData artifactData = new ArtifactData(artifactWithHeat); + Either origArtifact = titanDao.getNode(artifactData.getUniqueIdKey(), + artifactData.getUniqueId(), ArtifactData.class); + assertTrue(origArtifact.isLeft()); + ArtifactData origArtifactData = origArtifact.left().value(); + assertTrue(artifactWithHeat.getArtifactVersion() + .equals(origArtifactData.getArtifactDataDefinition().getArtifactVersion())); + + Either parameterNodeAfterDelete = titanDao + .getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), HeatParameterData.class); + assertTrue(parameterNodeAfterDelete.isLeft()); + + // verify new artifact and new parameter + ArtifactDefinition artifactDefinitionUpdated = updateArifact.left().value(); + ArtifactData artifactDataUpdated = new ArtifactData(artifactDefinitionUpdated); + Either updatedArtifact = titanDao + .getNode(artifactDataUpdated.getUniqueIdKey(), artifactDataUpdated.getUniqueId(), ArtifactData.class); + assertTrue(updatedArtifact.isLeft()); + ArtifactData updatedArtifactData = updatedArtifact.left().value(); + assertTrue(atifactToUpdate.getArtifactVersion() + .equals(updatedArtifactData.getArtifactDataDefinition().getArtifactVersion())); + assertFalse( + ((String) updatedArtifactData.getUniqueId()).equalsIgnoreCase((String) origArtifactData.getUniqueId())); + + List heatParametersAfterUpdate = artifactDefinitionUpdated.getHeatParameters(); + assertNotNull(heatParametersAfterUpdate); + assertTrue(heatParametersAfterUpdate.size() == 1); + HeatParameterDefinition UpdatedHeatParameter = heatParametersAfterUpdate.get(0); + assertFalse(UpdatedHeatParameter.getUniqueId().equalsIgnoreCase((String) parameterData.getUniqueId())); + Either parameterNodeAfterUpdate = titanDao.getNode( + new HeatParameterData(UpdatedHeatParameter).getUniqueIdKey(), UpdatedHeatParameter.getUniqueId(), + HeatParameterData.class); + assertTrue(parameterNodeAfterUpdate.isLeft()); + + // delete new artifact + Either removeArifact = artifactOperation.removeArifactFromResource( + RESOURCE_ID_2, artifactDefinitionUpdated.getUniqueId(), NodeTypeEnum.Resource, true, false); + assertTrue(removeArifact.isLeft()); + + // verify old artifact and parameter still exist + origArtifact = titanDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class); + assertTrue(origArtifact.isLeft()); + origArtifactData = origArtifact.left().value(); + assertTrue(artifactWithHeat.getArtifactVersion() + .equals(origArtifactData.getArtifactDataDefinition().getArtifactVersion())); + + parameterNodeAfterDelete = titanDao.getNode(parameterData.getUniqueIdKey(), parameterData.getUniqueId(), + HeatParameterData.class); + assertTrue(parameterNodeAfterDelete.isLeft()); + + // verify new artifact is deleted + Either artifactAfterDelete = titanDao + .getNode(artifactDataUpdated.getUniqueIdKey(), artifactDataUpdated.getUniqueId(), ArtifactData.class); + assertTrue(artifactAfterDelete.isRight()); + + parameterNodeAfterDelete = titanDao.getNode(new HeatParameterData(UpdatedHeatParameter).getUniqueIdKey(), + new HeatParameterData(UpdatedHeatParameter).getUniqueId(), HeatParameterData.class); + assertTrue(parameterNodeAfterDelete.isRight()); + + artifactOperation.removeArifactFromResource(RESOURCE_ID, artifactWithHeat.getUniqueId(), NodeTypeEnum.Resource, + true, false); + titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID), ResourceMetadataData.class); + titanDao.deleteNode(new UniqueIdData(NodeTypeEnum.Resource, RESOURCE_ID_2), ResourceMetadataData.class); + } + + private ArtifactDefinition createResourceWithHeat() { + ResourceMetadataData resource = createResource(RESOURCE_ID); + ArtifactDefinition artifactDefinition = createArtifactDefinition(USER_ID, RESOURCE_ID, ARTIFACT_NAME); + artifactDefinition.setArtifactType("HEAT"); + artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); + + List heatParams = new ArrayList(); + HeatParameterDefinition heatParam = new HeatParameterDefinition(); + heatParam.setCurrentValue("11"); + heatParam.setDefaultValue("22"); + heatParam.setDescription("desc"); + heatParam.setName("myParam"); + heatParam.setType("number"); + heatParams.add(heatParam); + artifactDefinition.setHeatParameters(heatParams); + + Either artifact = artifactOperation + .addArifactToComponent(artifactDefinition, RESOURCE_ID, NodeTypeEnum.Resource, true, false); + assertTrue(artifact.isLeft()); + ArtifactDefinition artifactWithHeat = artifact.left().value(); + return artifactWithHeat; + } + + private ArtifactDefinition addArtifactToService(String userId, String serviceId, String artifactName) { + ArtifactDefinition artifactInfo = createArtifactDefinition(userId, serviceId, artifactName); + + Either artifact = artifactOperation + .addArifactToComponent(artifactInfo, serviceId, NodeTypeEnum.Service, true, true); + assertTrue(artifact.isLeft()); + return artifact.left().value(); + } + + private ArtifactDefinition createArtifactDefinition(String userId, String serviceId, String artifactName) { + ArtifactDefinition artifactInfo = new ArtifactDefinition(); + + artifactInfo.setArtifactName(artifactName + ".sh"); + artifactInfo.setArtifactType("SHELL"); + artifactInfo.setDescription("hdkfhskdfgh"); + artifactInfo.setArtifactChecksum("UEsDBAoAAAAIAAeLb0bDQz"); + + artifactInfo.setUserIdCreator(userId); + String fullName = "Jim H"; + artifactInfo.setUpdaterFullName(fullName); + long time = System.currentTimeMillis(); + artifactInfo.setCreatorFullName(fullName); + artifactInfo.setCreationDate(time); + artifactInfo.setLastUpdateDate(time); + artifactInfo.setUserIdLastUpdater(userId); + artifactInfo.setArtifactLabel(artifactName); + artifactInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(serviceId, artifactInfo.getArtifactLabel())); + return artifactInfo; + } + + public Service createService(String userId, CategoryDefinition category, String serviceName, String serviceVersion, + boolean isHighestVersion) { + + Service service = buildServiceMetadata(userId, category, serviceName, serviceVersion); + + service.setHighestVersion(isHighestVersion); + + Either result = serviceOperation.createService(service, true); + + log.info(result.toString()); + assertTrue(result.isLeft()); + Service resultService = result.left().value(); + + // assertEquals("check resource unique id", + // UniqueIdBuilder.buildServiceUniqueId(serviceName, serviceVersion), + // resultService.getUniqueId()); + assertEquals("check resource state", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + resultService.getLifecycleState()); + + return resultService; + } + + private Service buildServiceMetadata(String userId, CategoryDefinition category, String serviceName, + String serviceVersion) { + + Service service = new Service(); + service.setName(serviceName); + service.setVersion(serviceVersion); + service.setDescription("description 1"); + + service.setCreatorUserId(userId); + service.setContactId("contactId@sdc.com"); + List categories = new ArrayList<>(); + categories.add(category); + service.setCategories(categories); + service.setIcon("images/my.png"); + List tags = new ArrayList(); + tags.add("TAG1"); + tags.add("TAG2"); + service.setTags(tags); + return service; + } + + private void deleteAndCreateCategory(String category) { + String[] names = category.split("/"); + OperationTestsUtil.deleteAndCreateServiceCategory(category, titanDao); + OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao); + } + + private UserData deleteAndCreateUser(String userId, String firstName, String lastName, String role) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + if (role != null && !role.isEmpty()) { + userData.setRole(role); + } else { + userData.setRole("ADMIN"); + } + + titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanDao.createNode(userData, UserData.class); + titanDao.commit(); + + return userData; + } + + public ResourceMetadataData createResource(String resourceName) { + + ResourceMetadataData serviceData1 = new ResourceMetadataData(); + serviceData1.getMetadataDataDefinition().setUniqueId(resourceName); + Either createNode = titanDao.createNode(serviceData1, + ResourceMetadataData.class); + + assertTrue("check resource created", createNode.isLeft()); + return createNode.left().value(); + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperationTest.java new file mode 100644 index 0000000000..5b8420d5dc --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperationTest.java @@ -0,0 +1,345 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.annotation.Resource; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.CapabilityTypeOperation; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint; +import org.openecomp.sdc.common.api.ConfigurationListener; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +// @TestExecutionListeners(listeners = { +// DependencyInjectionTestExecutionListener.class, +// DirtiesContextTestExecutionListener.class, +// TransactionalTestExecutionListener.class }) +public class CapabilityTypeOperationTest extends ModelTestBase { + + @Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + @Resource(name = "capability-type-operation") + private CapabilityTypeOperation capabilityTypeOperation; + + @BeforeClass + public static void setupBeforeClass() { + // ExternalConfiguration.setAppName("catalog-model"); + // String appConfigDir = "src/test/resources/config/catalog-model"; + // ConfigurationSource configurationSource = new + // FSConfigurationSource(ExternalConfiguration.getChangeListener(), + // appConfigDir); + + // configurationManager = new ConfigurationManager( + // new ConfigurationSource() { + // + // @Override + // public T getAndWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public void addWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // + // } + // }); + // + // Configuration configuration = new Configuration(); + // configuration.setTitanInMemoryGraph(true); + // + // configurationManager.setConfiguration(configuration); + ModelTestBase.init(); + + } + + @Test + public void testDummy() { + + assertTrue(capabilityTypeOperation != null); + + } + + @Test + public void testAddCapabilityType() { + + CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(); + capabilityTypeDefinition.setDescription("desc1"); + capabilityTypeDefinition.setType("tosca.capabilities.Container1"); + + Either addCapabilityType1 = capabilityTypeOperation + .addCapabilityType(capabilityTypeDefinition, true); + assertEquals("check capability type added", true, addCapabilityType1.isLeft()); + + CapabilityTypeDefinition capabilityTypeAdded = addCapabilityType1.left().value(); + compareBetweenCreatedToSent(capabilityTypeDefinition, capabilityTypeAdded); + + Either capabilityTypeByUid = capabilityTypeOperation + .getCapabilityTypeByUid(capabilityTypeAdded.getUniqueId()); + compareBetweenCreatedToSent(capabilityTypeByUid.left().value(), capabilityTypeDefinition); + + Either addCapabilityType2 = capabilityTypeOperation + .addCapabilityType(capabilityTypeDefinition, true); + assertEquals("check capability type failed", true, addCapabilityType2.isRight()); + assertEquals("check returned error", StorageOperationStatus.SCHEMA_VIOLATION, + addCapabilityType2.right().value()); + + } + + @Test + public void testAddDerviedCapabilityType() { + + CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(); + capabilityTypeDefinition.setDescription("desc1"); + capabilityTypeDefinition.setType("tosca.capabilities.Container2"); + capabilityTypeDefinition.setDerivedFrom("derivedFrom"); + + Either addCapabilityType1 = capabilityTypeOperation + .addCapabilityType(capabilityTypeDefinition, true); + // assertEquals("check capability type parent not exist", + // StorageOperationStatus.INVALID_ID, + // addCapabilityType1.right().value()); + // TODO: esofer change to INVALID_ID + assertEquals("check capability type parent not exist", StorageOperationStatus.INVALID_ID, + addCapabilityType1.right().value()); + } + + public CapabilityTypeDefinition createCapability(String capabilityTypeName) { + + CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(); + capabilityTypeDefinition.setDescription("desc1"); + capabilityTypeDefinition.setType(capabilityTypeName); + + Map properties = new HashMap(); + + String propName1 = "disk_size"; + String propName2 = "num_cpus"; + + PropertyDefinition property1 = buildProperty1(); + + properties.put(propName1, property1); + + PropertyDefinition property2 = buildProperty2(); + + properties.put(propName2, property2); + + capabilityTypeDefinition.setProperties(properties); + + Either addCapabilityType1 = capabilityTypeOperation + .addCapabilityType(capabilityTypeDefinition, true); + + CapabilityTypeDefinition capabilityTypeDefinitionCreated = addCapabilityType1.left().value(); + Either capabilityType = capabilityTypeOperation + .getCapabilityType(capabilityTypeDefinitionCreated.getUniqueId(), true); + assertEquals("check capability type fetched", true, capabilityType.isLeft()); + CapabilityTypeDefinition fetchedCTD = capabilityType.left().value(); + + Map fetchedProps = fetchedCTD.getProperties(); + + compareProperties(fetchedProps, properties); + + return fetchedCTD; + + } + + @Test + public void testAddCapabilityTypeWithProperties() { + + CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(); + capabilityTypeDefinition.setDescription("desc1"); + capabilityTypeDefinition.setType("tosca.capabilities.Container3"); + + Map properties = new HashMap(); + + String propName1 = "disk_size"; + String propName2 = "num_cpus"; + + PropertyDefinition property1 = buildProperty1(); + + properties.put(propName1, property1); + + PropertyDefinition property2 = buildProperty2(); + + properties.put(propName2, property2); + + capabilityTypeDefinition.setProperties(properties); + + Either addCapabilityType1 = capabilityTypeOperation + .addCapabilityType(capabilityTypeDefinition, true); + + CapabilityTypeDefinition capabilityTypeDefinitionCreated = addCapabilityType1.left().value(); + Either capabilityType = capabilityTypeOperation + .getCapabilityType(capabilityTypeDefinitionCreated.getUniqueId()); + assertEquals("check capability type fetched", true, capabilityType.isLeft()); + CapabilityTypeDefinition fetchedCTD = capabilityType.left().value(); + + Map fetchedProps = fetchedCTD.getProperties(); + + compareProperties(fetchedProps, properties); + } + + private void compareProperties(Map first, Map second) { + + assertTrue("check properties are full or empty", + ((first == null && second == null) || (first != null && second != null))); + if (first != null) { + assertEquals("check properties size", first.size(), second.size()); + + for (Entry entry : first.entrySet()) { + + String propName = entry.getKey(); + PropertyDefinition secondPD = second.get(propName); + assertNotNull("Cannot find property " + propName + " in " + second, secondPD); + + PropertyDefinition firstPD = entry.getValue(); + + comparePropertyDefinition(firstPD, secondPD); + } + + } + + } + + @Test + public void testGetCapabilityTypeNotFound() { + + Either capabilityType = capabilityTypeOperation + .getCapabilityType("not_exists"); + assertEquals("check not found is returned", StorageOperationStatus.NOT_FOUND, capabilityType.right().value()); + + } + + private void comparePropertyDefinition(PropertyDefinition first, PropertyDefinition second) { + + assertTrue("check objects are full or empty", + ((first == null && second == null) || (first != null && second != null))); + if (first != null) { + assertTrue("check property default value", compareValue(first.getDefaultValue(), second.getDefaultValue())); + assertTrue("check property description", compareValue(first.getDescription(), second.getDescription())); + assertTrue("check property type", compareValue(first.getType(), second.getType())); + compareList(first.getConstraints(), second.getConstraints()); + } + + } + + private void compareList(List first, List second) { + + assertTrue("check lists are full or empty", + ((first == null && second == null) || (first != null && second != null))); + if (first != null) { + assertEquals("check list size", first.size(), second.size()); + } + } + + private PropertyDefinition buildProperty2() { + PropertyDefinition property2 = new PropertyDefinition(); + property2.setDefaultValue("2"); + property2.setDescription("Number of (actual or virtual) CPUs associated with the Compute node."); + property2.setType(ToscaType.INTEGER.name().toLowerCase()); + List constraints3 = new ArrayList(); + List range = new ArrayList(); + range.add("1"); + range.add("4"); + + InRangeConstraint propertyConstraint3 = new InRangeConstraint(range); + constraints3.add(propertyConstraint3); + // property2.setConstraints(constraints3); + property2.setConstraints(constraints3); + return property2; + } + + private PropertyDefinition buildProperty1() { + PropertyDefinition property1 = new PropertyDefinition(); + property1.setDefaultValue("10"); + property1.setDescription( + "Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node."); + property1.setType(ToscaType.INTEGER.name().toLowerCase()); + List constraints = new ArrayList(); + GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0"); + constraints.add(propertyConstraint1); + + LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10"); + constraints.add(propertyConstraint2); + + property1.setConstraints(constraints); + return property1; + } + + private void compareBetweenCreatedToSent(CapabilityTypeDefinition x, CapabilityTypeDefinition y) { + + assertTrue(compareValue(x.getDerivedFrom(), y.getDerivedFrom())); + assertTrue(compareValue(x.getType(), y.getType())); + assertTrue(compareValue(x.getDescription(), y.getDescription())); + + } + + public boolean compareValue(String first, String second) { + + if (first == null && second == null) { + return true; + } + if (first != null) { + return first.equals(second); + } else { + return false; + } + } + + public void setOperations(TitanGenericDao titanDao, CapabilityTypeOperation capabilityTypeOperation) { + this.titanDao = titanDao; + this.capabilityTypeOperation = capabilityTypeOperation; + + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationSpringTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationSpringTest.java new file mode 100644 index 0000000000..2dcb1ee72e --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationSpringTest.java @@ -0,0 +1,543 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +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 java.util.function.Function; +import java.util.stream.Collectors; + +import javax.annotation.Resource; + +import org.apache.tinkerpop.gremlin.structure.io.IoCore; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +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.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.PropertyDefinition; +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.StorageOperationStatus; +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.LifecycleOperation; +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.model.operations.impl.util.OperationTestsUtil; +import org.openecomp.sdc.be.model.operations.impl.util.ResourceCreationUtils; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.unittests.utils.FactoryUtils; +import org.openecomp.sdc.be.unittests.utils.FactoryUtils.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class ComponentInstanceOperationSpringTest extends ModelTestBase { + private static Logger log = LoggerFactory.getLogger(ComponentInstanceOperationSpringTest.class.getName()); + @Resource(name = "component-instance-operation") + private ComponentInstanceOperation componentInstanceOperation; + + @Resource(name = "component-instance-operation") + private ComponentInstanceOperation resourceInstanceOperation; + + @Resource(name = "capability-type-operation") + private CapabilityTypeOperation capabilityTypeOperation; + + @Resource(name = "capability-operation") + public CapabilityOperation capabilityOperation; + + @Resource(name = "service-operation") + private ServiceOperation serviceOperation; + + @Resource(name = "resource-operation") + private ResourceOperation resourceOperation; + + @Resource(name = "property-operation") + private PropertyOperation propertyOperation; + + @Resource(name = "lifecycle-operation") + private LifecycleOperation lifecycleOperation; + + TitanGenericDao titanGenericDao; + + private static String CATEGORY_NAME = "category/mycategory"; + + User rfcUser; + + @BeforeClass + public static void setupBeforeClass() { + ModelTestBase.init(); + + } + + @Before + public void cleanUp() { + titanGenericDao = componentInstanceOperation.titanGenericDao; + Either graphResult = titanGenericDao.getGraph(); + TitanGraph graph = graphResult.left().value(); + + Iterable vertices = graph.query().vertices(); + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + vertex.remove(); + } + + } + titanGenericDao.commit(); + deleteAndCreateCategory(CATEGORY_NAME); + UserData modifierData = deleteAndCreateUser(ResourceCreationUtils.MODIFIER_ATT_UID + "rfc", + ResourceCreationUtils.MODIFIER_FIRST_NAME, ResourceCreationUtils.MODIFIER_LAST_NAME, "ADMIN"); + rfcUser = convertUserDataToUser(modifierData); + } + + @Test + public void testAddCapabilityPropertyValuesToResourceInstance() { + String rootName = "Root123"; + org.openecomp.sdc.be.model.Resource rootResource = createResource(rfcUser.getUserId(), CATEGORY_NAME, rootName, + "1.0", null, false, true); + + // certification request + Either requestCertificationResult = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Resource, rootResource, rfcUser, rfcUser, false); + assertTrue(requestCertificationResult.isLeft()); + + org.openecomp.sdc.be.model.Resource resultResource = (org.openecomp.sdc.be.model.Resource) requestCertificationResult + .left().value(); + + // start certification + Either startCertificationResult = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Resource, resultResource, rfcUser, rfcUser, false); + assertEquals(true, startCertificationResult.isLeft()); + + Either certifiedResourceRes = lifecycleOperation + .certifyComponent(NodeTypeEnum.Resource, rootResource, rfcUser, rfcUser, false); + assertTrue(certifiedResourceRes.isLeft()); + + CapabilityTypeDefinition capabilityType = buildCapabilityType(); + Either capabilityTypeRes = capabilityTypeOperation + .addCapabilityType(capabilityType); + assertTrue(capabilityTypeRes.isLeft()); + + CapabilityData capData = FactoryUtils.createCapabilityData(); + CapabilityDefinition capabilityDefinitionRoot = FactoryUtils + .convertCapabilityDataToCapabilityDefinitionRoot(capData); + + Either addCapabilityRootRes = capabilityOperation.addCapability( + (String) certifiedResourceRes.left().value().getUniqueId(), capabilityDefinitionRoot.getName(), + capabilityDefinitionRoot); + assertTrue(addCapabilityRootRes.isLeft()); + + String resourceName = "tosca.nodes.Apache.2.0"; + + CapabilityDefinition capabilityDefinition = FactoryUtils + .convertCapabilityDataToCapabilityDefinitionAddProperties(capData); + org.openecomp.sdc.be.model.Resource resource = createResource(rfcUser.getUserId(), CATEGORY_NAME, resourceName, + "0.1", rootName, false, true); + + Either addCapabilityRes = capabilityOperation + .addCapability((String) resource.getUniqueId(), capabilityDefinition.getName(), capabilityDefinition); + assertTrue(addCapabilityRes.isLeft()); + List properties = addCapabilityRes.left().value().getProperties(); + assertTrue(properties.size() == 2); + + Either clonedResourceRes = resourceOperation + .cloneComponent(resource, "0.2", false); + assertTrue(clonedResourceRes.isLeft()); + org.openecomp.sdc.be.model.Resource clonedResource = clonedResourceRes.left().value(); + + ComponentInstance instance = buildResourceInstance(clonedResource.getUniqueId(), "1", "tosca.nodes.Apache"); + + Service origService = createService(rfcUser.getUserId(), CATEGORY_NAME, "my-service", "1.0", true); + Either service2 = serviceOperation.getService(origService.getUniqueId(), + false); + assertTrue(service2.isLeft()); + origService = service2.left().value(); + + Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + String json = prettyGson.toJson(origService); + log.debug(json); + + Service fullService = origService; + + Either status = resourceInstanceOperation + .addComponentInstanceToContainerComponent((String) origService.getUniqueId(), NodeTypeEnum.Service, "1", + true, instance, NodeTypeEnum.Resource, false); + assertTrue(status.isLeft()); + + ComponentInstance resourceInstance = status.left().value(); + CapabilityDefinition capability = addCapabilityRes.left().value(); + capability.setName(capabilityDefinition.getName()); + List propertyValues = FactoryUtils.createComponentInstancePropertyList(); + capability.setProperties(propertyValues); + + Either>, TitanOperationStatus> addCPVsToRiRes = componentInstanceOperation + .addCapabilityPropertyValuesToResourceInstance(resourceInstance.getUniqueId(), capability, true); + assertTrue(addCPVsToRiRes.isLeft()); + + Either createService = serviceOperation.cloneService(fullService, "2.0", + false); + assertTrue(createService.isLeft()); + Map> capabilitiesMap = createService.left().value().getCapabilities(); + assertTrue(capabilitiesMap != null && capabilitiesMap.size() == 1); + Map capabilities = capabilitiesMap.values().iterator().next().stream() + .collect(Collectors.toMap(CapabilityDefinition::getName, Function.identity())); + assertTrue(capabilities.containsKey("Cap1") && capabilities.containsKey("Cap2")); + + // String outputFile = exportGraphMl(); + + } + + public String exportGraphMl() { + String result = null; + String outputFile = "C:\\Output" + File.separator + "exportGraph." + System.currentTimeMillis() + ".graphml"; + TitanGraph graph = titanGenericDao.getGraph().left().value(); + 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 CapabilityTypeDefinition buildCapabilityType() { + CapabilityTypeDefinition capabilityType = new CapabilityTypeDefinition(); + Map properties = new HashMap(); + + capabilityType.setType(Constants.DEFAULT_CAPABILITY_TYPE); + capabilityType.setProperties(properties); + + PropertyDefinition host = new PropertyDefinition(); + host.setUniqueId(UUID.randomUUID().toString()); + host.setName("host"); + host.setDefaultValue("captypehost"); + host.setType("string"); + + host.setSchema(new SchemaDefinition()); + host.getSchema().setProperty(new PropertyDataDefinition()); + host.getSchema().getProperty().setType("string"); + + PropertyDefinition port = new PropertyDefinition(); + port.setName("port"); + port.setDefaultValue("captypeport"); + port.setUniqueId(UUID.randomUUID().toString()); + port.setType("string"); + + port.setSchema(new SchemaDefinition()); + port.getSchema().setProperty(new PropertyDataDefinition()); + port.getSchema().getProperty().setType("string"); + + PropertyDefinition rootproperty = new PropertyDefinition(); + rootproperty.setName("captypeproperty"); + rootproperty.setDefaultValue("captypevalue"); + rootproperty.setUniqueId(UUID.randomUUID().toString()); + rootproperty.setType("string"); + + rootproperty.setSchema(new SchemaDefinition()); + rootproperty.getSchema().setProperty(new PropertyDataDefinition()); + rootproperty.getSchema().getProperty().setType("string"); + + properties.put("host", host); + properties.put("port", port); + properties.put("captypeproperty", rootproperty); + return capabilityType; + } + + private CapabilityInstData buildCapabilityInstanceData(String resourceInstanceId, CapabilityDefinition capability) { + CapabilityInstData capabilityInstance = new CapabilityInstData(); + Long creationTime = System.currentTimeMillis(); + String uniqueId = UniqueIdBuilder.buildCapabilityInstanceUid(resourceInstanceId, capability.getName()); + capabilityInstance.setCreationTime(creationTime); + capabilityInstance.setModificationTime(creationTime); + capabilityInstance.setUniqueId(uniqueId); + return capabilityInstance; + } + + private ComponentInstance buildResourceInstance(String respurceUid, String instanceNumber, String name) { + ComponentInstance resourceInstance = new ComponentInstance(); + resourceInstance.setName(name); + resourceInstance.setDescription("desc1"); + resourceInstance.setPosX("20"); + resourceInstance.setPosY("40"); + resourceInstance.setComponentUid(respurceUid); + resourceInstance.setCreationTime(System.currentTimeMillis()); + resourceInstance.setModificationTime(System.currentTimeMillis()); + resourceInstance.setNormalizedName(ResourceInstanceOperationTest.normaliseComponentInstanceName(name)); + return resourceInstance; + } + + public ResourceMetadataData createResource(String resourceName, TitanGenericDao titanGenericDao) { + ResourceMetadataData serviceData1 = new ResourceMetadataData(); + serviceData1.getMetadataDataDefinition().setUniqueId(resourceName); + Either createNode = titanGenericDao.createNode(serviceData1, + ResourceMetadataData.class); + assertTrue("check service created", createNode.isLeft()); + return createNode.left().value(); + } + + public ServiceMetadataData createServiceMetadataData(String serviceName, TitanGenericDao titanGenericDao) { + ServiceMetadataData serviceData1 = new ServiceMetadataData(); + serviceData1.getMetadataDataDefinition().setUniqueId(serviceName); + Either createNode = titanGenericDao.createNode(serviceData1, + ServiceMetadataData.class); + assertTrue("check service created", createNode.isLeft()); + return createNode.left().value(); + } + + public Service createService(String userId, String category, String serviceName, String serviceVersion, + boolean isHighestVersion) { + Service service = buildServiceMetadata(userId, category, serviceName, serviceVersion); + service.setHighestVersion(isHighestVersion); + Either result = serviceOperation.createService(service, true); + assertTrue(result.isLeft()); + Service resultService = result.left().value(); + assertEquals("check resource state", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + resultService.getLifecycleState()); + return resultService; + } + + private Service buildServiceMetadata(String userId, String category, String serviceName, String serviceVersion) { + Service service = new Service(); + service.setName(serviceName); + service.setVersion(serviceVersion); + service.setDescription("description 1"); + service.setCreatorUserId(userId); + service.setContactId("contactId@sdc.com"); + CategoryDefinition categoryDef = new CategoryDefinition(); + categoryDef.setName(category); + List categories = new ArrayList<>(); + categories.add(categoryDef); + service.setCategories(categories); + service.setIcon("images/my.png"); + List tags = new ArrayList(); + tags.add("TAG1"); + tags.add("TAG2"); + service.setTags(tags); + return service; + } + + private void deleteAndCreateCategory(String category) { + String[] names = category.split("/"); + OperationTestsUtil.deleteAndCreateServiceCategory(category, titanGenericDao); + OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanGenericDao); + } + + private UserData deleteAndCreateUser(String userId, String firstName, String lastName, String role) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + if (role != null && !role.isEmpty()) { + userData.setRole(role); + } else { + userData.setRole("ADMIN"); + } + titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanGenericDao.createNode(userData, UserData.class); + titanGenericDao.commit(); + return userData; + } + + public org.openecomp.sdc.be.model.Resource createResource(String userId, String category, String resourceName, + String resourceVersion, String parentResourceName, boolean isAbstract, boolean isHighestVersion) { + + String propName1 = "disk_size"; + String propName2 = "num_cpus"; + + List derivedFrom = new ArrayList(); + if (parentResourceName != null) { + derivedFrom.add(parentResourceName); + } + org.openecomp.sdc.be.model.Resource resource = buildResourceMetadata(userId, category, resourceName, + resourceVersion); + + resource.setAbstract(isAbstract); + resource.setHighestVersion(isHighestVersion); + + Map properties = new HashMap(); + + PropertyDefinition property1 = new PropertyDefinition(); + property1.setDefaultValue("10"); + property1.setDescription( + "Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node."); + property1.setType(ToscaType.INTEGER.name().toLowerCase()); + List constraints = new ArrayList(); + GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0"); + log.debug("{}", propertyConstraint1); + + constraints.add(propertyConstraint1); + + LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10"); + constraints.add(propertyConstraint2); + + property1.setConstraints(constraints); + + properties.put(propName1, property1); + + PropertyDefinition property2 = new PropertyDefinition(); + property2.setDefaultValue("2"); + property2.setDescription("Number of (actual or virtual) CPUs associated with the Compute node."); + property2.setType(ToscaType.INTEGER.name().toLowerCase()); + List constraints3 = new ArrayList(); + List range = new ArrayList(); + range.add("1"); + range.add("4"); + + InRangeConstraint propertyConstraint3 = new InRangeConstraint(range); + constraints3.add(propertyConstraint3); + property2.setConstraints(constraints3); + properties.put(propName2, property2); + + resource.setDerivedFrom(derivedFrom); + + resource.setProperties(convertMapToList(properties)); + + Either result = resourceOperation + .createResource(resource, true); + + assertTrue(result.isLeft()); + org.openecomp.sdc.be.model.Resource resultResource = result.left().value(); + assertEquals("check resource state", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + resultResource.getLifecycleState()); + + String resourceId = resultResource.getUniqueId(); + + Either either = propertyOperation.getPropertyOfResource(propName1, + resourceId); + + assertTrue(either.isLeft()); + PropertyDefinition propertyDefinition = either.left().value(); + assertEquals("check property default value", property1.getDefaultValue(), propertyDefinition.getDefaultValue()); + assertEquals("check property description", property1.getDescription(), propertyDefinition.getDescription()); + assertEquals("check property type", property1.getType(), propertyDefinition.getType()); + assertEquals("check property unique id", property1.getUniqueId(), propertyDefinition.getUniqueId()); + assertEquals("check property consitraints size", property1.getConstraints().size(), + propertyDefinition.getConstraints().size()); + + return resultResource; + } + + private org.openecomp.sdc.be.model.Resource buildResourceMetadata(String userId, String category, + String resourceName, String resourceVersion) { + + org.openecomp.sdc.be.model.Resource resource = new org.openecomp.sdc.be.model.Resource(); + resource.setName(resourceName); + resource.setVersion(resourceVersion); + ; + resource.setDescription("description 1"); + resource.setAbstract(false); + resource.setCreatorUserId(userId); + resource.setContactId("contactId@sdc.com"); + resource.setVendorName("vendor 1"); + resource.setVendorRelease("1.0.0"); + resource.setToscaResourceName(resourceName); + String[] categoryArr = category.split("/"); + resource.addCategory(categoryArr[0], categoryArr[1]); + resource.setIcon("images/my.png"); + List tags = new ArrayList(); + tags.add("TAG1"); + tags.add("TAG2"); + resource.setTags(tags); + return resource; + } + + 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; + } + + private User convertUserDataToUser(UserData modifierData) { + User modifier = new User(); + modifier.setUserId(modifierData.getUserId()); + modifier.setEmail(modifierData.getEmail()); + modifier.setFirstName(modifierData.getFirstName()); + modifier.setLastName(modifierData.getLastName()); + modifier.setRole(modifierData.getRole()); + return modifier; + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationTest.java new file mode 100644 index 0000000000..e77c9f0291 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationTest.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.be.model.operations.impl; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +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.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.operations.impl.ComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.unittests.utils.FactoryUtils; + +import fj.data.Either; + +public class ComponentInstanceOperationTest { + + @InjectMocks + ComponentInstanceOperation componentInstanceOperation = new ComponentInstanceOperation(); + @InjectMocks + private TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class); + + @Before + public void beforeTest() { + Mockito.reset(titanGenericDao); + MockitoAnnotations.initMocks(this); + } + + @Test + public void testGetCapabilities() { + + ComponentInstance ri = FactoryUtils.createResourceInstance(); + CapabilityData capData = FactoryUtils.createCapabilityData(); + Either>, TitanOperationStatus> childNodesReturned = prepareChildNodeRetValue( + capData); + + Mockito.when(titanGenericDao.getChildrenNodes(Mockito.anyString(), Mockito.anyString(), + Mockito.any(GraphEdgeLabels.class), Mockito.any(NodeTypeEnum.class), Mockito.any())) + .thenReturn(childNodesReturned); + + // ImmutablePair>> instanceAndCapabilities = + // componentInstanceOperation.getCapabilities(ri, + // NodeTypeEnum.Resource); + + Either>, TitanOperationStatus> instanceAndCapabilities = componentInstanceOperation + .getCapabilities(ri, NodeTypeEnum.Resource); + + // assertTrue(instanceAndCapabilities.left.getUniqueId().equals(ri.getUniqueId())); + assertTrue(instanceAndCapabilities.left().value().size() == 1); + assertTrue(instanceAndCapabilities.left().value().get(0).left.getUniqueId().equals(capData.getUniqueId())); + + } + + @Test + public void testGetRequirements() { + ComponentInstance ri = FactoryUtils.createResourceInstance(); + RequirementData reqData = FactoryUtils.createRequirementData(); + Either>, TitanOperationStatus> childNodesReturned = prepareChildNodeRetValue( + reqData); + + Mockito.when(titanGenericDao.getChildrenNodes(Mockito.anyString(), Mockito.anyString(), + Mockito.any(GraphEdgeLabels.class), Mockito.any(NodeTypeEnum.class), Mockito.any())) + .thenReturn(childNodesReturned); + + // ImmutablePair>> instanceAndCapabilities = + // componentInstanceOperation.getRequirements(ri, + // NodeTypeEnum.Resource); + Either>, TitanOperationStatus> instanceAndCapabilities = componentInstanceOperation + .getRequirements(ri, NodeTypeEnum.Resource); + + // assertTrue(instanceAndCapabilities.left.getUniqueId().equals(ri.getUniqueId())); + // assertTrue(instanceAndCapabilities.right.size() == 1); + // assertTrue(instanceAndCapabilities.right.get(0).left.getUniqueId().equals(reqData.getUniqueId())); + + assertTrue(instanceAndCapabilities.left().value().size() == 1); + assertTrue(instanceAndCapabilities.left().value().get(0).left.getUniqueId().equals(reqData.getUniqueId())); + + } + + private CapabilityInstData buildCapabilityInstanceData(String resourceInstanceId, CapabilityDefinition capability) { + CapabilityInstData capabilityInstance = new CapabilityInstData(); + Long creationTime = System.currentTimeMillis(); + String uniqueId = UniqueIdBuilder.buildCapabilityInstanceUid(resourceInstanceId, capability.getName()); + + capabilityInstance.setCreationTime(creationTime); + capabilityInstance.setModificationTime(creationTime); + capabilityInstance.setUniqueId(uniqueId); + + return capabilityInstance; + } + + private Either>, TitanOperationStatus> prepareChildNodeRetValue( + GraphNode data) { + ImmutablePair pair = new ImmutablePair<>(data, FactoryUtils.createGraphEdge()); + List> retList = new ArrayList<>(); + retList.add(pair); + return Either.left(retList); + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperationTest.java new file mode 100644 index 0000000000..14018d31f9 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperationTest.java @@ -0,0 +1,395 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import com.thinkaurelius.titan.core.TitanTransaction; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +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.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +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.ComponentParametersView; +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.operations.api.ICapabilityOperation; +import org.openecomp.sdc.be.model.operations.api.IRequirementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +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.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.unittests.utils.FactoryUtils; + +import fj.data.Either; + +public class ComponentOperationTest { + @InjectMocks + ComponentOperation compOperation = getAnnonimusImpl(); + + ComponentInstanceOperation componentInstanceOperation = Mockito.mock(ComponentInstanceOperation.class); + TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class); + ICapabilityOperation capabilityOperation = Mockito.mock(ICapabilityOperation.class); + IRequirementOperation requirementOperation = Mockito.mock(IRequirementOperation.class); + + @Before + public void beforeTest() { + Mockito.reset(componentInstanceOperation, requirementOperation, capabilityOperation); + MockitoAnnotations.initMocks(this); + } + + @Test + public void testGetCapabilities() { + Resource vf = FactoryUtils.createVF(); + ComponentInstance ri = FactoryUtils.createResourceInstance(); + CapabilityData capData = FactoryUtils.createCapabilityData(); + + FactoryUtils.addComponentInstanceToVF(vf, ri); + Either>, TitanOperationStatus> capDataList = prepareCompOperationReturnValue( + ri, capData); + + prepareMocksForCapabilitiesMethods(ri, capDataList); + + Map> capabilities = compOperation + .getCapabilities(vf, NodeTypeEnum.Resource, false).left().value(); + assertTrue(capabilities.size() == 1); + Entry> entry = capabilities.entrySet().iterator().next(); + assertTrue(entry.getKey().equals(capData.getType())); + assertTrue(entry.getValue().size() == 1); + assertTrue(entry.getValue().get(0).getUniqueId().equals(capData.getUniqueId())); + } + + @Test + public void testGetRequirments() { + Resource vf = FactoryUtils.createVF(); + ComponentInstance ri = FactoryUtils.createResourceInstance(); + + RequirementData reqData = FactoryUtils.createRequirementData(); + + FactoryUtils.addComponentInstanceToVF(vf, ri); + + Either>, TitanOperationStatus> reqDataEdgeList = prepareCompOperationReturnValue( + ri, reqData); + + prepareMocksForRequirmenetsMethods(ri, reqDataEdgeList); + + Map> requirements = compOperation + .getRequirements(vf, NodeTypeEnum.Resource, false).left().value(); + assertTrue(requirements.size() == 1); + Entry> entry = requirements.entrySet().iterator().next(); + assertTrue(entry.getKey().equals(FactoryUtils.Constants.DEFAULT_CAPABILITY_TYPE)); + assertTrue(entry.getValue().size() == 1); + assertTrue(entry.getValue().get(0).getUniqueId().equals(reqData.getUniqueId())); + } + + private void prepareMocksForRequirmenetsMethods(ComponentInstance ri, + Either>, TitanOperationStatus> reqDataEdgeList) { + + when(componentInstanceOperation.getRequirements(ri, NodeTypeEnum.Resource)).thenReturn(reqDataEdgeList); + when(requirementOperation.getRequirement(Mockito.anyString())).then(createReqDefAnswer()); + } + + private void prepareMocksForCapabilitiesMethods(ComponentInstance ri, + Either>, TitanOperationStatus> capDataList) { + when(componentInstanceOperation.getCapabilities(ri, NodeTypeEnum.Resource)).thenReturn(capDataList); + when(capabilityOperation.getCapabilityByCapabilityData(Mockito.any(CapabilityData.class))) + .then(createCapDefByDataAnswer()); + List> capInstList = new ArrayList<>(); + CapabilityInstData curCapabilityInst = FactoryUtils.createCapabilityInstData(); + GraphEdge edge = new GraphEdge(); + Map properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), + capDataList.left().value().get(0).getLeft().getUniqueId()); + edge.setProperties(properties); + ImmutablePair pair = new ImmutablePair( + curCapabilityInst, edge); + capInstList.add(pair); + when(titanGenericDao.getChildrenNodes( + UniqueIdBuilder.getKeyByNodeType( + NodeTypeEnum.getByNameIgnoreCase(ri.getOriginType().getInstanceType().trim())), + ri.getUniqueId(), GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, + CapabilityInstData.class)).thenReturn(Either.left(capInstList)); + + when(titanGenericDao.getChild( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(curCapabilityInst.getLabel())), + curCapabilityInst.getUniqueId(), GraphEdgeLabels.INSTANCE_OF, NodeTypeEnum.Capability, + CapabilityData.class)).thenReturn(Either.left(capDataList.left().value().get(0))); + + PropertyValueData propertyValueData = FactoryUtils.createPropertyData(); + ImmutablePair propPair = new ImmutablePair( + propertyValueData, null); + List> propPairList = new ArrayList<>(); + propPairList.add(propPair); + when(titanGenericDao.getChildrenNodes( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(curCapabilityInst.getLabel())), + curCapabilityInst.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, + PropertyValueData.class)).thenReturn(Either.left(propPairList)); + + CapabilityDefinition capDef = FactoryUtils + .convertCapabilityDataToCapabilityDefinitionAddProperties(capDataList.left().value().get(0).getLeft()); + List propDefList = capDef.getProperties().stream().filter(p -> p.getName().equals("host")) + .collect(Collectors.toList()); + PropertyDefinition propDef = propDefList.get(0); + PropertyData propData = FactoryUtils.convertCapabilityDefinitionToCapabilityData(propDef); + + ImmutablePair defPropPair = new ImmutablePair(propData, edge); + + when(titanGenericDao.getChild( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(propertyValueData.getLabel())), + propertyValueData.getUniqueId(), GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, + PropertyData.class)).thenReturn(Either.left(defPropPair)); + List capDefList = new ArrayList<>(); + capDefList.add(capDef); + when(componentInstanceOperation.updateCapDefPropertyValues(Mockito.any(ComponentInstance.class), + Mockito.any(List.class))).thenReturn(Either.left(capDefList)); + } + + private Either>, TitanOperationStatus> prepareCompOperationReturnValue( + ComponentInstance ri, Data data) { + ImmutablePair dataEdgePair = new ImmutablePair<>(data, new GraphEdge()); + List> dataEdgeList = new ArrayList<>(); + dataEdgeList.add(dataEdgePair); + return Either.left(dataEdgeList); + } + + private Answer> createReqDefAnswer() { + return new Answer>() { + + @Override + public Either answer(InvocationOnMock invocation) + throws Throwable { + String reqDataId = (String) invocation.getArguments()[0]; + return Either.left(FactoryUtils.convertRequirementDataIDToRequirementDefinition(reqDataId)); + } + }; + } + + private Answer> createCapDefByDataAnswer() { + return new Answer>() { + + @Override + public Either answer(InvocationOnMock invocation) + throws Throwable { + CapabilityData capData = (CapabilityData) invocation.getArguments()[0]; + return Either.left(FactoryUtils.convertCapabilityDataToCapabilityDefinitionAddProperties(capData)); + } + }; + } + + private ComponentOperation getAnnonimusImpl() { + return new ComponentOperation() { + + @Override + protected StorageOperationStatus validateCategories(Component currentComponent, Component component, + ComponentMetadataData componentData, NodeTypeEnum type) { + // TODO Auto-generated method stub + return null; + } + + @Override + protected StorageOperationStatus updateDerived(Component component, + Component currentComponent, ComponentMetadataData updatedResourceData, Class clazz) { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Either updateComponent(T component, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either increaseAndGetComponentInstanceCounter(String componentId, + boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + protected ComponentMetadataData getMetaDataFromComponent(Component component) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either getLightComponent(String id, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Either getComponentByNameAndVersion(String name, String version, + Map additionalParams, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either getComponent(String id, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + // @Override + // public Either + // getComponent_tx(String id, boolean inTransaction) { + // // TODO Auto-generated method stub + // return null; + // } + + @Override + public Either, StorageOperationStatus> getAdditionalArtifacts(String resourceId, + boolean recursively, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either cloneComponent(T other, String version, + boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Component getDefaultComponent() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isComponentExist(String componentId) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Either getMetadataComponent(String id, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) { + // TODO Auto-generated method stub + return null; + } + + @Override + TitanOperationStatus setComponentCategoriesFromGraph(Component component) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either validateComponentNameExists(String componentName) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either markComponentToDelete(Component componentToDelete, + boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either deleteComponent(String id, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either isComponentInUse(String componentId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either, StorageOperationStatus> getAllComponentsMarkedForDeletion() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either cloneComponent(T other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either getComponent(String id, + ComponentParametersView componentParametersView, boolean inTrasnaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Either, StorageOperationStatus> getFilteredComponents(Map filters, + boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Either updateComponentFilterResult(T component, + boolean inTransaction, ComponentParametersView filterParametersView) { + // TODO Auto-generated method stub + return null; + } + + }; + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java new file mode 100644 index 0000000000..a529074db6 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.operations.impl.ElementOperation; +import org.openecomp.sdc.be.model.operations.impl.util.OperationTestsUtil; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class ElementOperationTest extends ModelTestBase { + + @javax.annotation.Resource(name = "element-operation") + private ElementOperation elementOperation; + + @javax.annotation.Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + private static String CATEGORY = "category"; + private static String SUBCATEGORY = "subcategory"; + + @BeforeClass + public static void setupBeforeClass() { + // ExternalConfiguration.setAppName("catalog-model"); + // String appConfigDir = "src/test/resources/config/catalog-model"; + // ConfigurationSource configurationSource = new + // FSConfigurationSource(ExternalConfiguration.getChangeListener(), + // appConfigDir); + + ModelTestBase.init(); + + } + + @Test + public void testGetArtifactsTypes() { + + List artifactTypesCfg = new ArrayList(); + artifactTypesCfg.add("type1"); + artifactTypesCfg.add("type2"); + artifactTypesCfg.add("type3"); + artifactTypesCfg.add("type4"); + configurationManager.getConfiguration().setArtifactTypes(artifactTypesCfg); + Either, ActionStatus> allArtifactTypes = elementOperation.getAllArtifactTypes(); + assertTrue(allArtifactTypes.isLeft()); + assertEquals(artifactTypesCfg.size(), allArtifactTypes.left().value().size()); + + artifactTypesCfg.remove(0); + allArtifactTypes = elementOperation.getAllArtifactTypes(); + assertTrue(allArtifactTypes.isLeft()); + assertEquals(artifactTypesCfg.size(), allArtifactTypes.left().value().size()); + + artifactTypesCfg.add("type5"); + } + + // @Test + public void testGetResourceAndServiceCategoty() { + String id = OperationTestsUtil.deleteAndCreateResourceCategory(CATEGORY, SUBCATEGORY, titanDao); + + Either res = elementOperation.getCategory(NodeTypeEnum.ResourceNewCategory, + id); + assertTrue(res.isLeft()); + CategoryDefinition categoryDefinition = (CategoryDefinition) res.left().value(); + assertEquals(CATEGORY, categoryDefinition.getName()); + assertEquals(SUBCATEGORY, categoryDefinition.getSubcategories().get(0).getName()); + + id = OperationTestsUtil.deleteAndCreateServiceCategory(CATEGORY, titanDao); + + res = elementOperation.getCategory(NodeTypeEnum.ServiceNewCategory, id); + assertTrue(res.isLeft()); + categoryDefinition = (CategoryDefinition) res.left().value(); + assertEquals(CATEGORY, categoryDefinition.getName()); + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperationTest.java new file mode 100644 index 0000000000..6765557bab --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperationTest.java @@ -0,0 +1,289 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +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.HeatParameterDefinition; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.heat.HeatParameterType; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.HeatParametersOperation; +import org.openecomp.sdc.be.resources.data.HeatParameterData; +import org.openecomp.sdc.be.resources.data.HeatParameterValueData; + +import fj.data.Either; + +public class HeatParametersOperationTest extends ModelTestBase { + + HeatParametersOperation heatParametersOperation = new HeatParametersOperation(); + + TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class); + + @Before + public void setup() { + heatParametersOperation.setTitanGenericDao(titanGenericDao); + + } + + @Test + public void addPropertyToResourceTest() { + + String propName = "myProp"; + HeatParameterDefinition property = buildHeatPropertyDefinition(); + + HeatParameterData propertyData = new HeatParameterData(property); + + Either either = Either.left(propertyData); + + GraphRelation graphRelation = new GraphRelation(); + Either relationResult = Either.left(graphRelation); + + when(titanGenericDao.createNode((HeatParameterData) anyObject(), eq(HeatParameterData.class))) + .thenReturn(either); + when(titanGenericDao.createRelation((GraphNode) anyObject(), (GraphNode) anyObject(), + eq(GraphEdgeLabels.HEAT_PARAMETER), anyMap())).thenReturn(relationResult); + + Either result = heatParametersOperation.addPropertyToGraph(propName, + property, "resourceId.artifactId", NodeTypeEnum.ArtifactRef); + + assertTrue(result.isLeft()); + + } + + @Test + public void addPropertyListToResourceTest() { + + HeatParameterDefinition property = buildHeatPropertyDefinition(); + HeatParameterDefinition property2 = buildHeatPropertyDefinition(); + property2.setName("p2"); + + List parameters = new ArrayList(); + parameters.add(property); + parameters.add(property2); + + HeatParameterData propertyData = new HeatParameterData(property); + + Either either = Either.left(propertyData); + + GraphRelation graphRelation = new GraphRelation(); + Either relationResult = Either.left(graphRelation); + + when(titanGenericDao.createNode((HeatParameterData) anyObject(), eq(HeatParameterData.class))) + .thenReturn(either); + when(titanGenericDao.createRelation((GraphNode) anyObject(), (GraphNode) anyObject(), + eq(GraphEdgeLabels.HEAT_PARAMETER), anyMap())).thenReturn(relationResult); + + StorageOperationStatus result = heatParametersOperation.addPropertiesToGraph(parameters, + "resourceId.artifactId", NodeTypeEnum.ArtifactRef); + + assertEquals(StorageOperationStatus.OK, result); + + } + + @Test + public void testStringValues() { + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.STRING, "50aaa")); + } + + @Test + public void testNumberValues() { + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "50")); + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "50.5")); + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "0x11")); + + assertFalse(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "aaa")); + assertFalse(heatParametersOperation.isValidValue(HeatParameterType.NUMBER, "?>!")); + } + + @Test + public void testJsonValues() { + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.JSON, "{ \"member\" : \"50\"}")); + HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition( + HeatParameterType.JSON.getType(), "{ \"member\" : \"50\"}"); + StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition); + assertEquals(StorageOperationStatus.OK, operationStatus); + assertEquals(HeatParameterType.JSON.getType(), propertyDefinition.getType()); + + } + + @Test + public void testListValues() { + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.COMMA_DELIMITED_LIST, "one, two")); + HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition( + HeatParameterType.COMMA_DELIMITED_LIST.getType(), "one, two"); + StorageOperationStatus operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition); + assertEquals(StorageOperationStatus.OK, operationStatus); + assertEquals(HeatParameterType.COMMA_DELIMITED_LIST.getType(), propertyDefinition.getType()); + assertEquals("one, two", propertyDefinition.getDefaultValue()); + } + + @Test + public void testBooleanValues() { + + String[] trueArray = { "true", "t", "1", "on", "y", "yes" }; + String[] falseArray = { "false", "f", "0", "off", "n", "no" }; + + for (int i = 0; i < trueArray.length; i++) { + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i])); + HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition( + HeatParameterType.BOOLEAN.getType(), trueArray[i]); + StorageOperationStatus operationStatus = heatParametersOperation + .validateAndUpdateProperty(propertyDefinition); + assertEquals(StorageOperationStatus.OK, operationStatus); + assertEquals("true", propertyDefinition.getDefaultValue()); + + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i])); + propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), + trueArray[i].toUpperCase()); + operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition); + assertEquals(StorageOperationStatus.OK, operationStatus); + assertEquals("true", propertyDefinition.getDefaultValue()); + + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, trueArray[i])); + propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), + trueArray[i].toLowerCase()); + operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition); + assertEquals(StorageOperationStatus.OK, operationStatus); + assertEquals("true", propertyDefinition.getDefaultValue()); + } + + for (int i = 0; i < falseArray.length; i++) { + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i])); + HeatParameterDefinition propertyDefinition = buildHeatBooleanPropertyDefinition( + HeatParameterType.BOOLEAN.getType(), falseArray[i]); + StorageOperationStatus operationStatus = heatParametersOperation + .validateAndUpdateProperty(propertyDefinition); + assertEquals(StorageOperationStatus.OK, operationStatus); + assertEquals("false", propertyDefinition.getDefaultValue()); + + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i])); + propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), + falseArray[i].toUpperCase()); + operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition); + assertEquals(StorageOperationStatus.OK, operationStatus); + assertEquals("false", propertyDefinition.getDefaultValue()); + + assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, falseArray[i])); + propertyDefinition = buildHeatBooleanPropertyDefinition(HeatParameterType.BOOLEAN.getType(), + falseArray[i].toLowerCase()); + operationStatus = heatParametersOperation.validateAndUpdateProperty(propertyDefinition); + assertEquals(StorageOperationStatus.OK, operationStatus); + assertEquals("false", propertyDefinition.getDefaultValue()); + } + + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "true")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "t")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "1")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "on")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "y")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "yes")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "false")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "f")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "0")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "off")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "n")); + // assertTrue(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, + // "no")); + + assertFalse(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, "blabla")); + assertFalse(heatParametersOperation.isValidValue(HeatParameterType.BOOLEAN, "2")); + } + + private HeatParameterDefinition buildHeatPropertyDefinition() { + HeatParameterDefinition parameter = new HeatParameterDefinition(); + + parameter.setName("p1"); + parameter.setType("string"); + parameter.setDefaultValue("def"); + parameter.setCurrentValue("current"); + parameter.setDescription("description"); + + return parameter; + } + + private HeatParameterDefinition buildHeatBooleanPropertyDefinition(String type, String boolValue) { + HeatParameterDefinition parameter = new HeatParameterDefinition(); + + parameter.setName("parameter1"); + parameter.setType(type); + parameter.setDefaultValue(boolValue); + parameter.setDescription("description"); + + return parameter; + } + + @Test + public void addPropertyToResourceInstanceTest() { + + HeatParameterDefinition property = buildHeatPropertyDefinition(); + + HeatParameterValueData propertyData = new HeatParameterValueData(); + propertyData.setUniqueId("bla"); + propertyData.setValue("value1"); + + Either either = Either.left(propertyData); + + GraphRelation graphRelation = new GraphRelation(); + Either relationResult = Either.left(graphRelation); + + when(titanGenericDao.createNode((HeatParameterValueData) anyObject(), eq(HeatParameterValueData.class))) + .thenReturn(either); + when(titanGenericDao.createRelation((GraphNode) anyObject(), (GraphNode) anyObject(), + eq(GraphEdgeLabels.PARAMETER_VALUE), anyMap())).thenReturn(relationResult); + when(titanGenericDao.createRelation((GraphNode) anyObject(), (GraphNode) anyObject(), + eq(GraphEdgeLabels.PARAMETER_IMPL), anyMap())).thenReturn(relationResult); + + Either result = heatParametersOperation + .addHeatValueToGraph(property, "artifactLabel", "resourceInstanceId.artifactId", "resourceInstanceId"); + + assertTrue(result.isLeft()); + + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/InterfaceOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/InterfaceOperationTest.java new file mode 100644 index 0000000000..e1eb7db070 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/InterfaceOperationTest.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.be.model.operations.impl; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.util.OperationTestsUtil; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class InterfaceOperationTest { + private static Logger log = LoggerFactory.getLogger(InterfaceOperationTest.class.getName()); + private Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + + private static String USER_ID = "muserId"; + private static String CATEGORY_NAME = "category/mycategory"; + // InterfaceLifecycleOperation interfaceOperation = new + // InterfaceLifecycleOperation(); + + // TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class); + @javax.annotation.Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + @javax.annotation.Resource(name = "interface-operation") + private InterfaceLifecycleOperation interfaceOperation; + + @javax.annotation.Resource(name = "resource-operation") + private ResourceOperation resourceOperation; + + @javax.annotation.Resource(name = "property-operation") + private PropertyOperation propertyOperation; + + // @Resource(name = "artifact-operation") + // private ArtifactOperation artifactOperation; + + @Before + public void createUserAndCategory() { + deleteAndCreateCategory(CATEGORY_NAME); + deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID); + } + + @BeforeClass + public static void setupBeforeClass() { + // ExternalConfiguration.setAppName("catalog-model"); + // String appConfigDir = "src/test/resources/config/catalog-model"; + // ConfigurationSource configurationSource = new + // FSConfigurationSource(ExternalConfiguration.getChangeListener(), + // appConfigDir); + + ModelTestBase.init(); + + } + + @Test + public void testDummy() { + + assertTrue(interfaceOperation != null); + + } + + @Test + public void addInterfaceToResourceTest() { + + String capabilityTypeName = "mycapability1"; + String reqName = "host"; + String reqNodeName = "tosca.nodes.Compute1"; + String rootName = "Root100"; + String softwareCompName = "tosca.nodes.SoftwareComponent"; + String computeNodeName = "tosca.nodes.Compute"; + String myResourceVersion = "300.0"; + String reqRelationship = "myrelationship"; + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "100.0", null, + true, true); + + String interfaceName = "standard"; + InterfaceDefinition interfaceDefinition = buildInterfaceDefinition(); + + Operation op = buildOperationDefinition(); + Map operations = new HashMap(); + operations.put("Create", op); + interfaceDefinition.setOperations(operations); + + Either result = interfaceOperation + .addInterfaceToResource(interfaceDefinition, rootResource.getUniqueId(), "standard"); + + assertTrue(result.isLeft()); + log.debug("{}", result.left().value()); + + Either getResourceRes = resourceOperation + .getResource(rootResource.getUniqueId()); + assertTrue(getResourceRes.isLeft()); + Resource resourceWithInterface = getResourceRes.left().value(); + Map interfaces = resourceWithInterface.getInterfaces(); + assertNotNull(interfaces); + assertFalse(interfaces.isEmpty()); + InterfaceDefinition interfaceDefinition2 = interfaces.get(interfaceName); + assertNotNull(interfaceDefinition2.getOperations()); + assertFalse(interfaceDefinition2.getOperations().isEmpty()); + + } + + @Test + public void updateInterfaceToResourceTest() { + + String reqName = "host"; + String rootName = "Root200"; + String softwareCompName = "tosca.nodes.SoftwareComponent"; + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "200.0", null, + true, true); + + String interfaceName = "standard"; + InterfaceDefinition interfaceDefinition = buildInterfaceDefinition(); + + Operation op = buildOperationDefinition(); + Map operations = new HashMap(); + operations.put("create", op); + interfaceDefinition.setOperations(operations); + + Either result = interfaceOperation + .addInterfaceToResource(interfaceDefinition, rootResource.getUniqueId(), "standard"); + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId()); + + assertTrue(fetchRootResource.isLeft()); + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "400.0", rootResource.getName(), true, true); + + assertTrue(result.isLeft()); + log.debug("{}", result.left().value()); + + addImplementationToOperation(op); + // String resourceId, String interfaceName, String + // operationName,Operation interf + + Either opResult = interfaceOperation + .updateInterfaceOperation(softwareComponent.getUniqueId(), "standard", "create", op); + // PrintGraph pg = new PrintGraph(); + // System.out.println(pg.buildGraphForWebgraphWiz(titanDao.getGraph().left().value())); + assertTrue(opResult.isLeft()); + log.debug("{}", opResult.left().value()); + + Either getResourceRes = resourceOperation + .getResource(softwareComponent.getUniqueId()); + assertTrue(getResourceRes.isLeft()); + Resource resourceWithInterface = getResourceRes.left().value(); + Map interfaces = resourceWithInterface.getInterfaces(); + assertNotNull(interfaces); + assertFalse(interfaces.isEmpty()); + InterfaceDefinition interfaceDefinition2 = interfaces.get(interfaceName); + assertNotNull(interfaceDefinition2.getOperations()); + assertFalse(interfaceDefinition2.getOperations().isEmpty()); + Operation operation = interfaceDefinition2.getOperations().get("create"); + assertNotNull(operation); + assertNotNull(operation.getImplementation()); + } + + private void addImplementationToOperation(Operation op) { + ArtifactDataDefinition artifactDataDef = new ArtifactDataDefinition(); + artifactDataDef.setArtifactChecksum("YTg2Mjg4MWJhNmI5NzBiNzdDFkMWI="); + artifactDataDef.setArtifactName("create_myRoot.sh"); + artifactDataDef.setArtifactLabel("create_myRoot"); + artifactDataDef.setArtifactType("SHELL"); + artifactDataDef.setDescription("good description"); + artifactDataDef.setEsId("esId"); + artifactDataDef.setUniqueId(op.getUniqueId() + "." + artifactDataDef.getArtifactLabel()); + ArtifactDefinition artifactDef = new ArtifactDefinition(artifactDataDef, "UEsDBAoAAAAIAAeLb0bDQz"); + op.setImplementation(artifactDef); + } + + private InterfaceDefinition buildInterfaceDefinition() { + InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); + interfaceDefinition.setType("tosca.interfaces.standard"); + interfaceDefinition.setCreationDate(new Long(101232)); + + return interfaceDefinition; + } + + private Operation buildOperationDefinition() { + Operation op = new Operation(); + op.setCreationDate(new Long(101232)); + op.setDescription("asda"); + + return op; + } + + private void deleteAndCreateCategory(String category) { + String[] names = category.split("/"); + OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao); + } + + private UserData deleteAndCreateUser(String userId, String firstName, String lastName) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + + titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanDao.createNode(userData, UserData.class); + titanDao.commit(); + + return userData; + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperationTest.java new file mode 100644 index 0000000000..2b090f6f9f --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperationTest.java @@ -0,0 +1,1991 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; +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.components.ServiceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +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.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.PropertyConstraint; +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.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.util.OperationTestsUtil; +import org.openecomp.sdc.be.model.operations.impl.util.ResourceCreationUtils; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.InterfaceData; +import org.openecomp.sdc.be.resources.data.OperationData; +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.UserData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thinkaurelius.titan.core.TitanGraph; +//import com.tinkerpop.blueprints.Vertex; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class LifecycleOperationTest extends ModelTestBase { + private static Logger log = LoggerFactory.getLogger(LifecycleOperationTest.class.getName()); + private static final String CAPABILITY_HOSTED_ON = "HostedOn"; + + private static final String INTERFACE_OPERATION_CREATE = "create"; + + private static final String INTERFACE_NAME = "standard"; + + private static final String CATEGORY_NAME = "category/mycategory"; + + private static final String SERVICE_NAME = "myService"; + + private static final String REQUIREMENT_NAME = "requirementName"; + + private static final String CAPABILITY_NAME = "capName"; + + private static final String USER_ID = "muserId"; + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @javax.annotation.Resource + private ResourceOperation resourceOperation; + + @javax.annotation.Resource + private ServiceOperation serviceOperation; + + @javax.annotation.Resource + private LifecycleOperation lifecycleOperation; + + @javax.annotation.Resource + private CapabilityTypeOperation capabilityTypeOperation; + + @javax.annotation.Resource + private ArtifactOperation artifactOperation; + + @javax.annotation.Resource + private InterfaceLifecycleOperation interfaceOperation; + + @javax.annotation.Resource(name = "property-operation") + private PropertyOperation propertyOperation; + + @javax.annotation.Resource(name = "capability-operation") + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource(name = "component-instance-operation") + private ComponentInstanceOperation resourceInstanceOperation; + + @javax.annotation.Resource(name = "requirement-operation") + private RequirementOperation requirementOperation; + + User checkoutUser; + User checkinUser; + User rfcUser; + User testerUser; + User adminUser; + + @Rule + public TestName name = new TestName(); + + @BeforeClass + public static void initLifecycleOperation() { + ModelTestBase.init(); + // new ConfigurationSource() { + // + // @Override + // public T getAndWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public void addWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // + // } + // }); + // + + } + + @Before + public void setupBefore() { + clearGraph(); + UserData modifierData = deleteAndCreateUser(ResourceCreationUtils.MODIFIER_ATT_UID + "co", + ResourceCreationUtils.MODIFIER_FIRST_NAME, ResourceCreationUtils.MODIFIER_LAST_NAME, "ADMIN"); + checkoutUser = convertUserDataToUser(modifierData); + + modifierData = deleteAndCreateUser(ResourceCreationUtils.MODIFIER_ATT_UID + "ci", + ResourceCreationUtils.MODIFIER_FIRST_NAME, ResourceCreationUtils.MODIFIER_LAST_NAME, "ADMIN"); + checkinUser = convertUserDataToUser(modifierData); + + modifierData = deleteAndCreateUser(ResourceCreationUtils.MODIFIER_ATT_UID + "rfc", + ResourceCreationUtils.MODIFIER_FIRST_NAME, ResourceCreationUtils.MODIFIER_LAST_NAME, "ADMIN"); + rfcUser = convertUserDataToUser(modifierData); + + modifierData = deleteAndCreateUser(ResourceCreationUtils.MODIFIER_ATT_UID + "tester", + ResourceCreationUtils.MODIFIER_FIRST_NAME, ResourceCreationUtils.MODIFIER_LAST_NAME, "TESTER"); + testerUser = convertUserDataToUser(modifierData); + + modifierData = deleteAndCreateUser(ResourceCreationUtils.MODIFIER_ATT_UID + "admin", + ResourceCreationUtils.MODIFIER_FIRST_NAME, ResourceCreationUtils.MODIFIER_LAST_NAME, "ADMIN"); + adminUser = convertUserDataToUser(modifierData); + + modifierData = deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID, "ADMIN"); + adminUser = convertUserDataToUser(modifierData); + + String[] category = CATEGORY_NAME.split("/"); + OperationTestsUtil.deleteAndCreateServiceCategory(CATEGORY_NAME, titanGenericDao); + OperationTestsUtil.deleteAndCreateResourceCategory(category[0], category[1], titanGenericDao); + + } + + @After + public void teardown() { + clearGraph(); + } + + private void clearGraph() { + Either graphResult = titanGenericDao.getGraph(); + TitanGraph graph = graphResult.left().value(); + + Iterable vertices = graph.query().vertices(); + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + // graph.removeVertex(vertex); + vertex.remove(); + } + + } + titanGenericDao.commit(); + } + + @Test + public void getOwnerTest() { + + Resource resultResource = createTestResource(checkoutUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, null); + + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(resultResource.getUniqueId(), NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + assertEquals("check modifier", checkoutUser.getUserId(), resourceOwner.getUserId()); + + } + + /*********************** CHECKOUT ***************************************************************/ + + @Test + public void checkoutCertifiedTest() { + + Resource resultResource = createTestResource(adminUser.getUserId(), "1.0", LifecycleStateEnum.CERTIFIED, null); + String origUniqueId = resultResource.getUniqueId(); + Either origResourceResult = resourceOperation.getResource(origUniqueId); + Resource origResource = origResourceResult.left().value(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkout + Either checkoutResponse = (Either) lifecycleOperation + .checkoutComponent(NodeTypeEnum.Resource, resultResource, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkoutResponse.isLeft()); + Resource checkoutResource = checkoutResponse.left().value(); + + assertEquals(checkoutResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + assertEquals(checkoutResource.getVersion(), "1.1"); + assertEquals(checkoutResource.getCreatorUserId(), adminUser.getUserId()); + assertEquals(checkoutResource.getLastUpdaterUserId(), checkoutUser.getUserId()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(checkoutResource.getUniqueId(), NodeTypeEnum.Resource, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkoutUser)); + + // assert original resource not deleted + Either getOrigResource = resourceOperation.getResource(origUniqueId); + assertEquals("check resource created", true, getOrigResource.isLeft()); + // assertEquals("assert original resource not changed", origResource, + // getOrigResource.left().value()); + } + + @Test + public void checkoutDefaultTest() { + + Resource resultResource = createTestResource(checkinUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkout + Either checkoutResponse = (Either) lifecycleOperation + .checkoutComponent(NodeTypeEnum.Resource, resultResource, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkoutResponse.isLeft()); + Resource checkoutResource = checkoutResponse.left().value(); + + assertEquals(checkoutResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + assertEquals(checkoutResource.getVersion(), "0.2"); + assertEquals(checkoutResource.getCreatorUserId(), checkinUser.getUserId()); + assertEquals(checkoutResource.getLastUpdaterUserId(), checkoutUser.getUserId()); + assertEquals(checkoutResource.isHighestVersion(), true); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(checkoutResource.getUniqueId(), NodeTypeEnum.Resource, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkoutUser)); + + // assert original resource not deleted + Either getOrigResource = resourceOperation.getResource(origUniqueId); + assertEquals("check resource created", true, getOrigResource.isLeft()); + // assertEquals("assert original resource not changed", origResource, + // getOrigResource.left().value()); + assertEquals("assert original resource not highest version", false, + getOrigResource.left().value().isHighestVersion()); + } + + @Test + public void checkoutFullResourceTest() { + + Resource origResource = createFullTestResource(checkinUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + String origUniqueId = origResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkout + Either checkoutResponse = (Either) lifecycleOperation + .checkoutComponent(NodeTypeEnum.Resource, origResource, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkoutResponse.isLeft()); + Resource checkoutResource = checkoutResponse.left().value(); + + assertEquals(checkoutResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + assertEquals(checkoutResource.getVersion(), "0.2"); + assertEquals(checkoutResource.getCreatorUserId(), checkinUser.getUserId()); + assertEquals(checkoutResource.getLastUpdaterUserId(), checkoutUser.getUserId()); + assertEquals(checkoutResource.isHighestVersion(), true); + + assertNotNull(checkoutResource.getArtifacts()); + assertFalse(checkoutResource.getArtifacts().isEmpty()); + assertNotNull(checkoutResource.getInterfaces()); + assertFalse(checkoutResource.getInterfaces().isEmpty()); + Map interfaces = checkoutResource.getInterfaces(); + assertTrue(interfaces.containsKey(INTERFACE_NAME)); + InterfaceDefinition interfaceDef = interfaces.get(INTERFACE_NAME); + Map operations = interfaceDef.getOperations(); + assertNotNull(operations); + assertFalse(operations.isEmpty()); + assertTrue(operations.containsKey(INTERFACE_OPERATION_CREATE)); + Operation op = operations.get(INTERFACE_OPERATION_CREATE); + assertNotNull(op.getImplementation()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(checkoutResource.getUniqueId(), NodeTypeEnum.Resource, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkoutUser)); + + // assert original resource not deleted + Either getOrigResource = resourceOperation.getResource(origUniqueId); + assertEquals("check resource created", true, getOrigResource.isLeft()); + // assertEquals("assert original resource not changed", origResource, + // getOrigResource.left().value()); + assertEquals("assert original resource not highest version", false, + getOrigResource.left().value().isHighestVersion()); + } + + @Test + public void getResourceOwnerResourceNotExistTest() { + + // create resource metadata + Resource resource = buildResourceMetadata(adminUser.getUserId(), CATEGORY_NAME); + resource.setLifecycleState(LifecycleStateEnum.CERTIFIED); + resource.setUniqueId("my-resource.0.1"); + + Either origResourceResult = resourceOperation.getResource("my-resource.0.1"); + assertEquals("assert resource not exist", true, origResourceResult.isRight()); + + // get resource owner + + Either getOwnerResponse = lifecycleOperation.getComponentOwner("my-resource.0.1", + NodeTypeEnum.Resource, false); + + assertEquals("assert no owner", true, getOwnerResponse.isRight()); + StorageOperationStatus status = getOwnerResponse.right().value(); + + assertEquals(StorageOperationStatus.INVALID_ID, status); + + } + + @Test + public void checkoutResourceTwice() { + + Resource resultResource = createTestResource(adminUser.getUserId(), "1.0", LifecycleStateEnum.CERTIFIED, null); + String origUniqueId = resultResource.getUniqueId(); + Either origResourceResult = resourceOperation.getResource(origUniqueId); + Resource origResource = origResourceResult.left().value(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // first checkout + Either checkoutResponse1 = (Either) lifecycleOperation + .checkoutComponent(NodeTypeEnum.Resource, resultResource, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkoutResponse1.isLeft()); + + // second checkout + Either checkoutResponse2 = (Either) lifecycleOperation + .checkoutComponent(NodeTypeEnum.Resource, origResource, checkoutUser, resourceOwner, false); + assertEquals("check checkout failed", true, checkoutResponse2.isRight()); + assertEquals(StorageOperationStatus.ENTITY_ALREADY_EXISTS, checkoutResponse2.right().value()); + + } + + /******** SERVICE */ + @Test + public void checkoutServiceDefaultTest() { + + Service resultResource = createTestService(checkinUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkout + Either checkoutResponse = lifecycleOperation + .checkoutComponent(NodeTypeEnum.Service, resultResource, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkoutResponse.isLeft()); + Component checkoutResource = checkoutResponse.left().value(); + + assertEquals(checkoutResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + assertEquals(checkoutResource.getVersion(), "0.2"); + assertEquals(checkoutResource.getCreatorUserId(), checkinUser.getUserId()); + assertEquals(checkoutResource.getLastUpdaterUserId(), checkoutUser.getUserId()); + assertEquals(checkoutResource.isHighestVersion(), true); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(checkoutResource.getUniqueId(), NodeTypeEnum.Service, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkoutUser)); + + // assert original resource not deleted + Either getOrigResource = serviceOperation.getService(origUniqueId); + assertEquals("check resource created", true, getOrigResource.isLeft()); + // assertEquals("assert original resource not changed", origResource, + // getOrigResource.left().value()); + assertEquals("assert original resource not highest version", false, + getOrigResource.left().value().isHighestVersion()); + } + + @Test + public void checkoutFullServiceTest() { + + Service origService = createTestService(checkinUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + String origUniqueId = origService.getUniqueId(); + + // add artifacts + addArtifactToService(checkinUser.getUserId(), origService.getUniqueId(), "install_apache"); + addArtifactToService(checkinUser.getUserId(), origService.getUniqueId(), "start_apache"); + + // add resource instances + ResourceInstanceOperationTest riTest = new ResourceInstanceOperationTest(); + riTest.setOperations(titanGenericDao, capabilityTypeOperation, requirementOperation, capabilityOperation, + resourceOperation, propertyOperation, resourceInstanceOperation); + riTest.addResourceInstancesAndRelation(origService.getUniqueId()); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + Either serviceBeforeCheckout = serviceOperation.getService(origUniqueId, true); + assertTrue(serviceBeforeCheckout.isLeft()); + origService = serviceBeforeCheckout.left().value(); + + // checkout + Either checkoutResponse = lifecycleOperation + .checkoutComponent(NodeTypeEnum.Service, origService, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkoutResponse.isLeft()); + Service checkoutResource = (Service) checkoutResponse.left().value(); + + assertEquals(checkoutResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + assertEquals(checkoutResource.getVersion(), "0.2"); + assertEquals(checkoutResource.getCreatorUserId(), checkinUser.getUserId()); + assertEquals(checkoutResource.getLastUpdaterUserId(), checkoutUser.getUserId()); + assertEquals(checkoutResource.isHighestVersion(), true); + + assertNotNull(checkoutResource.getArtifacts()); + assertFalse(checkoutResource.getArtifacts().isEmpty()); + assertNotNull(checkoutResource.getComponentInstances()); + assertFalse(checkoutResource.getComponentInstances().isEmpty()); + assertNotNull(checkoutResource.getComponentInstancesRelations()); + assertFalse(checkoutResource.getComponentInstancesRelations().isEmpty()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(checkoutResource.getUniqueId(), NodeTypeEnum.Service, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkoutUser)); + + // assert original resource not deleted + Either getOrigResource = serviceOperation.getService(origUniqueId); + assertEquals("check service created", true, getOrigResource.isLeft()); + // assertEquals("assert original resource not changed", origResource, + // getOrigResource.left().value()); + assertEquals("assert original service not highest version", false, + getOrigResource.left().value().isHighestVersion()); + } + + @Test + public void checkoutServiceTwice() { + + Service resultResource = createTestService(adminUser.getUserId(), "1.0", LifecycleStateEnum.CERTIFIED, null); + String origUniqueId = resultResource.getUniqueId(); + Either origResourceResult = serviceOperation.getService(origUniqueId); + Service origResource = origResourceResult.left().value(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // first checkout + Either checkoutResponse1 = lifecycleOperation + .checkoutComponent(NodeTypeEnum.Service, resultResource, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkoutResponse1.isLeft()); + + // second checkout + Either checkoutResponse2 = lifecycleOperation + .checkoutComponent(NodeTypeEnum.Service, origResource, checkoutUser, resourceOwner, false); + assertEquals("check checkout failed", true, checkoutResponse2.isRight()); + assertEquals(StorageOperationStatus.ENTITY_ALREADY_EXISTS, checkoutResponse2.right().value()); + + } + + /**************************** CHECKIN ********************************************************************/ + + @Test + public void checkinDefaultTest() { + + Resource resultResource = createTestResource(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkin + Either checkinResponse = (Either) lifecycleOperation + .checkinComponent(NodeTypeEnum.Resource, resultResource, checkinUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkinResponse.isLeft()); + Resource checkinResource = checkinResponse.left().value(); + + assertEquals(checkinResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + assertEquals(checkinResource.getVersion(), "0.1"); + assertEquals(checkinResource.getCreatorUserId(), adminUser.getUserId()); + assertEquals(checkinResource.getLastUpdaterUserId(), checkinUser.getUserId()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(checkinResource.getUniqueId(), NodeTypeEnum.Resource, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkinUser)); + + } + + @Test + public void checkinFromRfcTest() { + + Resource resultResource = createTestResource(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkin + Either checkinResponse = (Either) lifecycleOperation + .checkinComponent(NodeTypeEnum.Resource, resultResource, checkinUser, resourceOwner, false); + assertEquals("check resource object is returned", true, checkinResponse.isLeft()); + + // rfc + Either rfcResponse = (Either) lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Resource, checkinResponse.left().value(), rfcUser, + checkinUser, false); + assertEquals("check resource object is returned", true, checkinResponse.isLeft()); + + // checkin (cancel rfc) + checkinResponse = (Either) lifecycleOperation + .checkinComponent(NodeTypeEnum.Resource, rfcResponse.left().value(), checkinUser, rfcUser, false); + assertEquals("check resource object is returned", true, checkinResponse.isLeft()); + resultResource = checkinResponse.left().value(); + + assertEquals(resultResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + assertEquals(resultResource.getVersion(), "0.1"); + assertEquals(resultResource.getCreatorUserId(), adminUser.getUserId()); + assertEquals(resultResource.getLastUpdaterUserId(), checkinUser.getUserId()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(resultResource.getUniqueId(), NodeTypeEnum.Resource, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkinUser)); + + // assert relations + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resultResource.getUniqueId()); + Map props = new HashMap(); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, + props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(checkinUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + } + + /*** SERVICE */ + @Test + public void checkinServiceDefaultTest() { + + Service resultService = createTestService(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, null); + String origUniqueId = resultService.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkin + Either checkinResponse = lifecycleOperation + .checkinComponent(NodeTypeEnum.Service, resultService, checkinUser, resourceOwner, false); + assertEquals("check service object is returned", true, checkinResponse.isLeft()); + Service checkinResource = (Service) checkinResponse.left().value(); + + assertEquals(checkinResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + assertEquals(checkinResource.getVersion(), "0.1"); + assertEquals(checkinResource.getCreatorUserId(), adminUser.getUserId()); + assertEquals(checkinResource.getLastUpdaterUserId(), checkinUser.getUserId()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(checkinResource.getUniqueId(), NodeTypeEnum.Service, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkinUser)); + + } + + @Test + public void checkinServiceFromRfcTest() { + + Service resultResource = createTestService(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkin + Either checkinResponse = lifecycleOperation + .checkinComponent(NodeTypeEnum.Service, resultResource, checkinUser, resourceOwner, false); + assertEquals("check service object is returned", true, checkinResponse.isLeft()); + + // rfc + Either rfcResponse = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, checkinResponse.left().value(), rfcUser, + checkinUser, false); + assertEquals("check service object is returned", true, checkinResponse.isLeft()); + + // checkin (cancel rfc) + checkinResponse = lifecycleOperation.checkinComponent(NodeTypeEnum.Service, rfcResponse.left().value(), + checkinUser, rfcUser, false); + assertEquals("check resource object is returned", true, checkinResponse.isLeft()); + resultResource = (Service) checkinResponse.left().value(); + + assertEquals(resultResource.getLifecycleState(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + assertEquals(resultResource.getVersion(), "0.1"); + assertEquals(resultResource.getCreatorUserId(), adminUser.getUserId()); + assertEquals(resultResource.getLastUpdaterUserId(), checkinUser.getUserId()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(resultResource.getUniqueId(), NodeTypeEnum.Service, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(checkinUser)); + + // assert relations + ServiceMetadataDataDefinition metadata = new ServiceMetadataDataDefinition(); + metadata.setUniqueId(resultResource.getUniqueId()); + ServiceMetadataData resourceData = new ServiceMetadataData(metadata); + Map props = new HashMap(); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, + props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(checkinUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + } + + /**************************** + * UNDO CHECKOUT + ********************************************************************/ + + @Test + public void undoCheckoutNewResourceTest() { + + Resource resultResource = createTestResource(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // + + // undo checkout + Either undoCheckoutResponse = (Either) lifecycleOperation + .undoCheckout(NodeTypeEnum.Resource, resultResource, adminUser, resourceOwner, false); + assertEquals("check resource object is returned", true, undoCheckoutResponse.isLeft()); + + Either origResourceResult = resourceOperation.getResource(origUniqueId); + assertTrue(origResourceResult.isRight()); + /* + * assertTrue(origResourceResult.isLeft()); + * assertTrue(origResourceResult.left().value().getIsDeleted() == true); + */ + } + + @Test + public void undoCheckoutNewFullResourceTest() { + + Resource resultResource = createFullTestResource(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // undo checkout + Either undoCheckoutResponse = (Either) lifecycleOperation + .undoCheckout(NodeTypeEnum.Resource, resultResource, adminUser, resourceOwner, false); + assertEquals("check resource object is returned", true, undoCheckoutResponse.isLeft()); + + Either origResourceResult = resourceOperation.getResource(origUniqueId); + /* + * assertTrue(origResourceResult.isLeft()); + * assertTrue(origResourceResult.left().value().getIsDeleted() == true); + */ assertTrue(origResourceResult.isRight()); + + String interfaceId = origUniqueId + "." + INTERFACE_NAME; + Either node = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceId, InterfaceData.class); + assertTrue(node.isRight()); + + String operationId = interfaceId + "." + INTERFACE_OPERATION_CREATE; + Either op = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InterfaceOperation), operationId, OperationData.class); + assertTrue(op.isRight()); + + String capabilityId = "capability." + origUniqueId + "." + CAPABILITY_NAME; + Either capability = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityId, CapabilityData.class); + assertTrue(capability.isRight()); + + String requirementId = origUniqueId + "." + REQUIREMENT_NAME; + Either req = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), requirementId, RequirementData.class); + assertTrue(req.isRight()); + + } + + @Test + public void undoCheckoutExistingResourceTest() { + + Resource resultResource = createTestResource(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + + // get resource owner + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(resultResource.getUniqueId(), NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + String prevResourceId = resultResource.getUniqueId(); + Either result2 = (Either) lifecycleOperation + .checkoutComponent(NodeTypeEnum.Resource, resultResource, checkoutUser, resourceOwner, false); + assertEquals("check resource created", true, result2.isLeft()); + Resource resultResource2 = result2.left().value(); + + // get resource owner + getOwnerResponse = lifecycleOperation.getComponentOwner(resultResource2.getUniqueId(), NodeTypeEnum.Resource, + false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + resourceOwner = getOwnerResponse.left().value(); + assertEquals(resourceOwner, checkoutUser); + + // undo checkout + Either undoCheckoutResponse = (Either) lifecycleOperation + .undoCheckout(NodeTypeEnum.Resource, resultResource2, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, undoCheckoutResponse.isLeft()); + + // get previous resource + Either resourceAfterUndo = resourceOperation.getResource(prevResourceId); + assertTrue(resourceAfterUndo.isLeft()); + Resource actualResource = resourceAfterUndo.left().value(); + assertTrue(actualResource.isHighestVersion()); + assertEquals(adminUser.getUserId(), actualResource.getCreatorUserId()); + assertEquals(adminUser.getUserId(), actualResource.getLastUpdaterUserId()); + assertEquals("0.1", actualResource.getVersion()); + assertEquals(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, actualResource.getLifecycleState()); + + Either origResourceResult = resourceOperation + .getResource(resultResource2.getUniqueId()); + /* + * assertTrue(origResourceResult.isLeft()); + * assertTrue(origResourceResult.left().value().getIsDeleted() == true); + */ assertTrue(origResourceResult.isRight()); + + } + + /**** SERVICE ***/ + @Test + public void undoCheckoutNewServiceTest() { + + Service resultResource = createTestService(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // + + // undo checkout + Either undoCheckoutResponse = lifecycleOperation + .undoCheckout(NodeTypeEnum.Service, resultResource, adminUser, resourceOwner, false); + assertEquals("check resource object is returned", true, undoCheckoutResponse.isLeft()); + + Either origResourceResult = serviceOperation.getService(origUniqueId); + /* + * assertTrue(origResourceResult.isLeft()); + * assertTrue(origResourceResult.left().value().getIsDeleted() == true); + */ assertTrue(origResourceResult.isRight()); + + } + + @Test + public void undoCheckoutNewFullServiceTest() { + + Service origService = createTestService(checkinUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + String origUniqueId = origService.getUniqueId(); + + // add artifacts + addArtifactToService(checkinUser.getUserId(), origService.getUniqueId(), "install_apache"); + addArtifactToService(checkinUser.getUserId(), origService.getUniqueId(), "start_apache"); + + // add resource instances + ResourceInstanceOperationTest riTest = new ResourceInstanceOperationTest(); + riTest.setOperations(titanGenericDao, capabilityTypeOperation, requirementOperation, capabilityOperation, + resourceOperation, propertyOperation, resourceInstanceOperation); + riTest.addResourceInstancesAndRelation(origService.getUniqueId()); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + Either service = serviceOperation.getService(origUniqueId); + assertTrue(service.isLeft()); + + Service resultResource = service.left().value(); + List resourceInstances = resultResource.getComponentInstances(); + + // undo checkout + Either undoCheckoutResponse = lifecycleOperation + .undoCheckout(NodeTypeEnum.Service, resultResource, adminUser, resourceOwner, false); + assertEquals("check resource object is returned", true, undoCheckoutResponse.isLeft()); + + Either origResourceResult = serviceOperation.getService(origUniqueId); + /* + * assertTrue(origResourceResult.isLeft()); + * assertTrue(origResourceResult.left().value().getIsDeleted() == true); + */ assertTrue(origResourceResult.isRight()); + + for (ComponentInstance ri : resourceInstances) { + Either node = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), ri.getUniqueId(), + ComponentInstanceData.class); + assertTrue(node.isRight()); + } + + } + + @Test + public void undoCheckoutExistingServiceTest() { + + Service resultResource = createTestService(adminUser.getUserId(), "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + + // get resource owner + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(resultResource.getUniqueId(), NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + String prevResourceId = resultResource.getUniqueId(); + Either result2 = lifecycleOperation + .checkoutComponent(NodeTypeEnum.Service, resultResource, checkoutUser, resourceOwner, false); + assertEquals("check resource created", true, result2.isLeft()); + Component resultResource2 = result2.left().value(); + String result2Uid = resultResource.getUniqueId(); + + // get resource owner + getOwnerResponse = lifecycleOperation.getComponentOwner(resultResource2.getUniqueId(), NodeTypeEnum.Resource, + false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + resourceOwner = getOwnerResponse.left().value(); + assertEquals(resourceOwner, checkoutUser); + + // undo checkout + Either undoCheckoutResponse = lifecycleOperation + .undoCheckout(NodeTypeEnum.Service, resultResource2, checkoutUser, resourceOwner, false); + assertEquals("check resource object is returned", true, undoCheckoutResponse.isLeft()); + + // get previous resource + Either resourceAfterUndo = serviceOperation.getService(prevResourceId); + assertTrue(resourceAfterUndo.isLeft()); + Service actualResource = resourceAfterUndo.left().value(); + assertTrue(actualResource.isHighestVersion()); + assertEquals(adminUser.getUserId(), actualResource.getCreatorUserId()); + assertEquals(adminUser.getUserId(), actualResource.getLastUpdaterUserId()); + assertEquals("0.1", actualResource.getVersion()); + assertEquals(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, actualResource.getLifecycleState()); + + Either origResourceResult = serviceOperation.getService(result2Uid); + /* + * assertTrue(origResourceResult.isLeft()); + * assertTrue(origResourceResult.left().value().getIsDeleted() == true); + */ assertTrue(origResourceResult.isRight()); + + } + + /**************************** + * CERTIFICATION REQUEST + ********************************************************************/ + + @Test + public void certReqDefaultTest() { + Resource actualResource = testCertificationRequest(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + + // assert relations + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(actualResource.getUniqueId()); + Map props = new HashMap(); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(adminUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + } + + @Test + public void atomicCheckinCertReqTest() { + Resource actualResource = testCertificationRequest(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + // assert relations + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(actualResource.getUniqueId()); + Map props = new HashMap(); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + } + + private Resource testCertificationRequest(LifecycleStateEnum preState) { + + Resource resultResource = createTestResource(adminUser.getUserId(), "0.1", preState, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkin + Either certReqResponse = (Either) lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Resource, resultResource, rfcUser, resourceOwner, false); + assertEquals("check resource object is returned", true, certReqResponse.isLeft()); + Resource resourceAfterChange = certReqResponse.left().value(); + + assertEquals(resourceAfterChange.getLifecycleState(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + assertEquals(resourceAfterChange.getVersion(), "0.1"); + assertEquals(resourceAfterChange.getCreatorUserId(), adminUser.getUserId()); + assertEquals(resourceAfterChange.getLastUpdaterUserId(), rfcUser.getUserId()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(resourceAfterChange.getUniqueId(), NodeTypeEnum.Resource, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(rfcUser)); + + return resourceAfterChange; + } + + /** SERVICE **/ + @Test + public void certServiceReqDefaultTest() { + Service actualResource = testServiceCertificationRequest(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + + // assert relations + ServiceMetadataDataDefinition metadata = new ServiceMetadataDataDefinition(); + metadata.setUniqueId(actualResource.getUniqueId()); + ServiceMetadataData serviceData = new ServiceMetadataData(metadata); + Map props = new HashMap(); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(serviceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(serviceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(adminUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + } + + @Test + public void atomicServiceCheckinCertReqTest() { + Service actualResource = testServiceCertificationRequest(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + // assert relations + ServiceMetadataDataDefinition metadata = new ServiceMetadataDataDefinition(); + metadata.setUniqueId(actualResource.getUniqueId()); + ServiceMetadataData serviceData = new ServiceMetadataData(metadata); + Map props = new HashMap(); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(serviceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(serviceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + } + + private Service testServiceCertificationRequest(LifecycleStateEnum preState) { + + Service resultResource = createTestService(adminUser.getUserId(), "0.1", preState, null); + String origUniqueId = resultResource.getUniqueId(); + + Either getOwnerResponse = lifecycleOperation.getComponentOwner(origUniqueId, + NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + + // checkin + Either certReqResponse = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultResource, rfcUser, resourceOwner, false); + assertEquals("check resource object is returned", true, certReqResponse.isLeft()); + Service resourceAfterChange = (Service) certReqResponse.left().value(); + + assertEquals(resourceAfterChange.getLifecycleState(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + assertEquals(resourceAfterChange.getVersion(), "0.1"); + assertEquals(resourceAfterChange.getCreatorUserId(), adminUser.getUserId()); + assertEquals(resourceAfterChange.getLastUpdaterUserId(), rfcUser.getUserId()); + + // assert owner changed + Either getOwnerCheckoutResponse = lifecycleOperation + .getComponentOwner(resourceAfterChange.getUniqueId(), NodeTypeEnum.Service, false); + assertEquals("check user object is returned", true, getOwnerCheckoutResponse.isLeft()); + resourceOwner = getOwnerCheckoutResponse.left().value(); + assertTrue(resourceOwner.equals(rfcUser)); + + return resourceAfterChange; + } + + /**************************** + * START CERTIFICATION + ********************************************************************/ + + @Test + public void startCertificationTest() { + + Resource resultResource = createTestResource(checkinUser.getUserId(), "0.2", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + + // certification request + Either requestCertificationResult = (Either) lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Resource, resultResource, rfcUser, checkinUser, false); + assertTrue(requestCertificationResult.isLeft()); + + // start certification + Either startCertificationResult = (Either) lifecycleOperation + .startComponentCertification(NodeTypeEnum.Resource, resultResource, testerUser, rfcUser, false); + + assertEquals(true, startCertificationResult.isLeft()); + Resource actualResource = startCertificationResult.left().value(); + + // get resource owner + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(actualResource.getUniqueId(), NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + assertEquals(testerUser.getUserId(), resourceOwner.getUserId()); + + assertTrue(actualResource.isHighestVersion()); + assertEquals(checkinUser.getUserId(), actualResource.getCreatorUserId()); + assertEquals(testerUser.getUserId(), actualResource.getLastUpdaterUserId()); + assertEquals(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS, actualResource.getLifecycleState()); + + // assert relations + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(actualResource.getUniqueId()); + Map props = new HashMap(); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(testerUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(checkinUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + } + + /** SERVICE */ + @Test + public void startServiceCertificationTest() { + + Service resultResource = createTestService(checkinUser.getUserId(), "0.2", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + + // certification request + Either requestCertificationResult = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultResource, rfcUser, checkinUser, false); + assertTrue(requestCertificationResult.isLeft()); + + // start certification + Either startCertificationResult = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultResource, testerUser, rfcUser, false); + + assertEquals(true, startCertificationResult.isLeft()); + Service actualResource = (Service) startCertificationResult.left().value(); + + // get resource owner + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(actualResource.getUniqueId(), NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + assertEquals(testerUser.getUserId(), resourceOwner.getUserId()); + + assertTrue(actualResource.isHighestVersion()); + assertEquals(checkinUser.getUserId(), actualResource.getCreatorUserId()); + assertEquals(testerUser.getUserId(), actualResource.getLastUpdaterUserId()); + assertEquals(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS, actualResource.getLifecycleState()); + + // assert relations + ServiceMetadataDataDefinition metadata = new ServiceMetadataDataDefinition(); + metadata.setUniqueId(actualResource.getUniqueId()); + ServiceMetadataData serviceData = new ServiceMetadataData(metadata); + Map props = new HashMap(); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(serviceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(testerUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(serviceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(serviceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(checkinUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + } + + /**************************** + * FAIL CERTIFICATION + ********************************************************************/ + + @Test + public void failCertificationTest() { + + Resource actualResource = certificationStatusChange(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, checkinUser); + + // assert relations + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(actualResource.getUniqueId()); + Map props = new HashMap(); + + // old edges removed + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + // new state is checkin + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, + props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(checkinUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + } + + /*** SERVICE **/ + + @Test + public void failCertificationServiceTest() { + + Service actualService = certificationStatusChangeService(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, checkinUser); + + // assert relations + ServiceMetadataData resourceData = new ServiceMetadataData((ServiceMetadataDataDefinition) actualService + .getComponentMetadataDefinition().getMetadataDataDefinition()); + Map props = new HashMap(); + + // old edges removed + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + // new state is checkin + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, + props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(checkinUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + } + + /**************************** + * CANCEL CERTIFICATION + ********************************************************************/ + + @Test + public void cancelCertificationTest() { + + Resource actualResource = certificationStatusChange(LifecycleStateEnum.READY_FOR_CERTIFICATION, rfcUser); + + // assert relations + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(actualResource.getUniqueId()); + Map props = new HashMap(); + + // old edges removed + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(checkinUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + // new state is rfc + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, + props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + } + + /** SERVICE **/ + @Test + public void cancelCertificationServiceTest() { + + Service actualService = certificationStatusChangeService(LifecycleStateEnum.READY_FOR_CERTIFICATION, rfcUser); + + // assert relations + ServiceMetadataData ServiceNode = new ServiceMetadataData(); + ServiceNode.getMetadataDataDefinition().setUniqueId(actualService.getUniqueId()); + Map props = new HashMap(); + + // old edges removed + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(ServiceNode, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(ServiceNode, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(checkinUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + // new state is rfc + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(ServiceNode, GraphEdgeLabels.STATE, + props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + } + + /**************************** CERTIFY ********************************************************************/ + + @Test + public void certifyTest() { + + Resource resultResource = createTestResource(checkinUser.getUserId(), "0.2", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + + // certification request + Either requestCertificationResult = (Either) lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Resource, resultResource, rfcUser, checkinUser, false); + assertTrue(requestCertificationResult.isLeft()); + + // start certification + Either startCertificationResult = (Either) lifecycleOperation + .startComponentCertification(NodeTypeEnum.Resource, resultResource, testerUser, rfcUser, false); + assertEquals(true, startCertificationResult.isLeft()); + Resource actualResource = startCertificationResult.left().value(); + + // cancel certification + Either CertificationResult = lifecycleOperation + .certifyComponent(NodeTypeEnum.Resource, actualResource, testerUser, testerUser, false); + + assertEquals(true, CertificationResult.isLeft()); + actualResource = (Resource) CertificationResult.left().value(); + + // get resource owner + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(actualResource.getUniqueId(), NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + assertEquals(testerUser.getUserId(), resourceOwner.getUserId()); + + assertTrue(actualResource.isHighestVersion()); + assertEquals(checkinUser.getUserId(), actualResource.getCreatorUserId()); + assertEquals(testerUser.getUserId(), actualResource.getLastUpdaterUserId()); + assertEquals(LifecycleStateEnum.CERTIFIED, actualResource.getLifecycleState()); + + // assert relations + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(actualResource.getUniqueId()); + Map props = new HashMap(); + + // old edges removed + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + // new state is certified + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, + props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(testerUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + } + + /******** SERVICE **/ + + @Test + public void certifyServiceTest() { + + Service resultService = createTestService(checkinUser.getUserId(), "0.2", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + + // certification request + Either requestCertificationResult = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultService, rfcUser, checkinUser, false); + assertTrue(requestCertificationResult.isLeft()); + + // start certification + Either startCertificationResult = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultService, testerUser, rfcUser, false); + assertEquals(true, startCertificationResult.isLeft()); + Service actualService = (Service) startCertificationResult.left().value(); + + // cancel certification + Either CertificationResult = lifecycleOperation + .certifyComponent(NodeTypeEnum.Service, actualService, testerUser, testerUser, false); + + assertEquals(true, CertificationResult.isLeft()); + actualService = (Service) CertificationResult.left().value(); + + // get resource owner + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(actualService.getUniqueId(), NodeTypeEnum.Service, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + assertEquals(testerUser.getUserId(), resourceOwner.getUserId()); + + assertTrue(actualService.isHighestVersion()); + assertEquals(checkinUser.getUserId(), actualService.getCreatorUserId()); + assertEquals(testerUser.getUserId(), actualService.getLastUpdaterUserId()); + assertEquals(LifecycleStateEnum.CERTIFIED, actualService.getLifecycleState()); + + // assert relations + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(actualService.getUniqueId()); + Map props = new HashMap(); + + // old edges removed + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either incomingRelationByCriteria = titanGenericDao + .getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isRight()); + + // new state is certified + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, GraphEdgeLabels.STATE, + props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(testerUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + incomingRelationByCriteria = titanGenericDao.getIncomingRelationByCriteria(resourceData, + GraphEdgeLabels.LAST_STATE, props); + assertTrue(incomingRelationByCriteria.isLeft()); + assertEquals(rfcUser.getUserId(), incomingRelationByCriteria.left().value().getFrom().getIdValue()); + + } + + @Test + public void testDeleteOldVersionsResource() { + // simulate + createTestResource(checkinUser.getUserId(), "1.0", LifecycleStateEnum.CERTIFIED, null); + Resource resourceNewVersion = createTestResource(checkinUser.getUserId(), "1.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + createTestResource(checkinUser.getUserId(), "1.2", LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, + resourceNewVersion.getUUID()); + createTestResource(checkinUser.getUserId(), "1.3", LifecycleStateEnum.CERTIFICATION_IN_PROGRESS, + resourceNewVersion.getUUID()); + Resource certifiedResource = createTestResource(checkinUser.getUserId(), "2.0", LifecycleStateEnum.CERTIFIED, + resourceNewVersion.getUUID()); + + Either deleteOldComponentVersions = lifecycleOperation + .deleteOldComponentVersions(NodeTypeEnum.Resource, certifiedResource.getName(), + certifiedResource.getUUID(), false); + + assertTrue(deleteOldComponentVersions.isLeft()); + + String resourceName = certifiedResource.getName(); + Either, StorageOperationStatus> resource = resourceOperation + .getResourceByNameAndVersion(resourceName, "1.0", false); + assertTrue(resource.isLeft()); + + resource = resourceOperation.getResourceByNameAndVersion(resourceName, "2.0", false); + assertTrue(resource.isLeft()); + + resource = resourceOperation.getResourceByNameAndVersion(resourceName, "1.1", false); + assertTrue(resource.isLeft()); + assertTrue(resource.left().value().size() == 1); + Resource deleted = resource.left().value().get(0); + assertTrue(deleted.getIsDeleted()); + // assertEquals(StorageOperationStatus.NOT_FOUND, + // resource.right().value()); + + resource = resourceOperation.getResourceByNameAndVersion(resourceName, "1.2", false); + // assertTrue(resource.isRight()); + // assertEquals(StorageOperationStatus.NOT_FOUND, + // resource.right().value()); + assertTrue(resource.isLeft()); + assertTrue(resource.left().value().size() == 1); + deleted = resource.left().value().get(0); + assertTrue(deleted.getIsDeleted()); + + resource = resourceOperation.getResourceByNameAndVersion(resourceName, "1.3", false); + // assertTrue(resource.isRight()); + // assertEquals(StorageOperationStatus.NOT_FOUND, + // resource.right().value()); + assertTrue(resource.isLeft()); + assertTrue(resource.left().value().size() == 1); + deleted = resource.left().value().get(0); + assertTrue(deleted.getIsDeleted()); + } + + @Test + public void testDeleteOldVersionsService() { + // simulate + createTestService(checkinUser.getUserId(), "1.0", LifecycleStateEnum.CERTIFIED, null); + Service serviceNewUUid = createTestService(checkinUser.getUserId(), "1.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + createTestService(checkinUser.getUserId(), "1.2", LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, + serviceNewUUid.getUUID()); + createTestService(checkinUser.getUserId(), "1.3", LifecycleStateEnum.CERTIFICATION_IN_PROGRESS, + serviceNewUUid.getUUID()); + Service certifiedService = createTestService(checkinUser.getUserId(), "2.0", LifecycleStateEnum.CERTIFIED, + serviceNewUUid.getUUID()); + + Either deleteOldComponentVersions = lifecycleOperation + .deleteOldComponentVersions(NodeTypeEnum.Service, certifiedService.getName(), + certifiedService.getUUID(), false); + + assertTrue(deleteOldComponentVersions.isLeft()); + + String resourceName = certifiedService.getName(); + Either service = serviceOperation.getServiceByNameAndVersion(resourceName, + "1.0", null, false); + assertTrue(service.isLeft()); + + service = serviceOperation.getServiceByNameAndVersion(resourceName, "2.0", null, false); + assertTrue(service.isLeft()); + + service = serviceOperation.getServiceByNameAndVersion(resourceName, "1.1", null, false); + /* + * assertTrue(resource.isRight()); + * assertEquals(StorageOperationStatus.NOT_FOUND, + * resource.right().value()); + */ + assertTrue(service.isLeft()); + assertTrue(service.left().value().getIsDeleted()); + + service = serviceOperation.getServiceByNameAndVersion(resourceName, "1.2", null, false); + + service = serviceOperation.getServiceByNameAndVersion(resourceName, "1.3", null, false); + /* + * assertTrue(service.isRight()); + * assertEquals(StorageOperationStatus.NOT_FOUND, + * service.right().value()); + */ + assertTrue(service.isLeft()); + assertTrue(service.left().value().getIsDeleted()); + + service = serviceOperation.getServiceByNameAndVersion(resourceName, "1.3", null, false); + /* + * assertTrue(service.isRight()); + * assertEquals(StorageOperationStatus.NOT_FOUND, + * service.right().value()); + */ + assertTrue(service.isLeft()); + assertTrue(service.left().value().getIsDeleted()); + + } + + private Resource certificationStatusChange(LifecycleStateEnum nextState, User expectedOwner) { + Resource resultResource = createTestResource(checkinUser.getUserId(), "0.2", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + + // certification request + Either requestCertificationResult = (Either) lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Resource, resultResource, rfcUser, checkinUser, false); + assertTrue(requestCertificationResult.isLeft()); + + // start certification + Either startCertificationResult = (Either) lifecycleOperation + .startComponentCertification(NodeTypeEnum.Resource, resultResource, testerUser, rfcUser, false); + assertEquals(true, startCertificationResult.isLeft()); + Resource actualResource = startCertificationResult.left().value(); + + // cancel certification + Either failCertificationResult = (Either) lifecycleOperation + .cancelOrFailCertification(NodeTypeEnum.Resource, actualResource, testerUser, testerUser, nextState, + false); + + assertEquals(true, failCertificationResult.isLeft()); + actualResource = failCertificationResult.left().value(); + + // get resource owner + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(actualResource.getUniqueId(), NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + assertEquals(expectedOwner, resourceOwner); + + assertTrue(actualResource.isHighestVersion()); + assertEquals(checkinUser.getUserId(), actualResource.getCreatorUserId()); + assertEquals(testerUser.getUserId(), actualResource.getLastUpdaterUserId()); + assertEquals(nextState, actualResource.getLifecycleState()); + return actualResource; + } + + private Service certificationStatusChangeService(LifecycleStateEnum nextState, User expectedOwner) { + Service resultService = createTestService(checkinUser.getUserId(), "0.2", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, null); + + // certification request + Either requestCertificationResult = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultService, rfcUser, checkinUser, false); + assertTrue(requestCertificationResult.isLeft()); + + // start certification + Either startCertificationResult = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultService, testerUser, rfcUser, false); + assertEquals(true, startCertificationResult.isLeft()); + Service actualService = (Service) startCertificationResult.left().value(); + + // cancel certification + Either failCertificationResult = lifecycleOperation + .cancelOrFailCertification(NodeTypeEnum.Service, actualService, testerUser, testerUser, nextState, + false); + + assertEquals(true, failCertificationResult.isLeft()); + actualService = (Service) failCertificationResult.left().value(); + + // get resource owner + Either getOwnerResponse = lifecycleOperation + .getComponentOwner(actualService.getUniqueId(), NodeTypeEnum.Resource, false); + + assertEquals("check user object is returned", true, getOwnerResponse.isLeft()); + User resourceOwner = getOwnerResponse.left().value(); + assertEquals(expectedOwner, resourceOwner); + + assertTrue(actualService.isHighestVersion()); + assertEquals(checkinUser.getUserId(), actualService.getCreatorUserId()); + assertEquals(testerUser.getUserId(), actualService.getLastUpdaterUserId()); + assertEquals(nextState, actualService.getLifecycleState()); + return actualService; + } + + private Resource createTestResource(String userId, String version, LifecycleStateEnum state, String uuid) { + // create resource in graph + + Resource resource2 = buildResourceMetadata(userId, CATEGORY_NAME); + resource2.setVersion(version); + ; + resource2.setLifecycleState(state); + resource2.setUUID(uuid); + + Either result = resourceOperation.createResource(resource2); + assertEquals("check resource created", true, result.isLeft()); + Resource resultResource = result.left().value(); + return resultResource; + } + + private Service createTestService(String userId, String version, LifecycleStateEnum state, String uuid) { + // create resource in graph + + Service service = new Service(); + service.setName(SERVICE_NAME); + service.setVersion(version); + service.setDescription("description 1"); + service.setCreatorUserId(userId); + service.setContactId("contactId@sdc.com"); + CategoryDefinition category = new CategoryDefinition(); + category.setName(CATEGORY_NAME); + + List categories = new ArrayList<>(); + categories.add(category); + service.setCategories(categories); + service.setIcon("images/my.png"); + List tags = new ArrayList(); + tags.add("TAG1"); + tags.add("TAG2"); + service.setTags(tags); + service.setUUID(uuid); + + service.setLifecycleState(state); + + Either result = serviceOperation.createService(service); + assertEquals("check service created", true, result.isLeft()); + Service resultResource = result.left().value(); + return resultResource; + } + + private Resource createFullTestResource(String userId, String version, LifecycleStateEnum state) { + + Resource resource2 = buildResourceMetadata(userId, CATEGORY_NAME); + resource2.setVersion(version); + ; + resource2.setLifecycleState(state); + + InterfaceDefinition inter = new InterfaceDefinition(INTERFACE_NAME, "interface description", null); + + Operation operation = new Operation(); + operation.setDescription("op description"); + operation.setUniqueId(inter.getUniqueId() + "." + INTERFACE_OPERATION_CREATE); + + ArtifactDataDefinition artifactDataDef = new ArtifactDataDefinition(); + artifactDataDef.setArtifactChecksum("YTg2Mjg4MWJhNmI5NzBiNzdDFkMWI="); + artifactDataDef.setArtifactName("create_myRoot.sh"); + artifactDataDef.setArtifactLabel("create_myRoot"); + artifactDataDef.setArtifactType("SHELL"); + artifactDataDef.setDescription("good description"); + artifactDataDef.setEsId("esId"); + artifactDataDef.setUniqueId(operation.getUniqueId() + "." + artifactDataDef.getArtifactLabel()); + ArtifactDefinition artifactDef = new ArtifactDefinition(artifactDataDef, "UEsDBAoAAAAIAAeLb0bDQz"); + + operation.setImplementation(artifactDef); + operation.setCreationDate(System.currentTimeMillis()); + Map ops = new HashMap<>(); + ops.put(INTERFACE_OPERATION_CREATE, operation); + inter.setOperations(ops); + + Map interfaces = new HashMap<>(); + interfaces.put(INTERFACE_NAME, inter); + + resource2.setInterfaces(interfaces); + + String capabilityTypeName = CAPABILITY_HOSTED_ON; + createCapabilityOnGraph(capabilityTypeName); + + // create capability definition + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setDescription("my capability"); + capabilityDefinition.setType(capabilityTypeName); + capabilityDefinition.setName(CAPABILITY_NAME); + Map> capabilities = new HashMap<>(); + List validSourceTypes = new ArrayList(); + validSourceTypes.add("tosca.nodes.SC"); + capabilityDefinition.setValidSourceTypes(validSourceTypes); + List caplist = new ArrayList(); + caplist.add(capabilityDefinition); + capabilities.put(capabilityTypeName, caplist); + resource2.setCapabilities(capabilities); + + // add requirement definition + RequirementDefinition reqDefinition = new RequirementDefinition(); + // reqDefinition.setNode(reqNodeName); + // reqDefinition.setRelationship(reqRelationship); + + reqDefinition.setCapability(capabilityTypeName); + reqDefinition.setName(REQUIREMENT_NAME); + Map> requirements = new HashMap<>(); + List reqlist = new ArrayList(); + reqlist.add(reqDefinition); + requirements.put(capabilityTypeName, reqlist); + resource2.setRequirements(requirements); + + Either result = resourceOperation.createResource(resource2); + assertEquals("check resource created", true, result.isLeft()); + Resource resultResource = result.left().value(); + + // add artifacts to resource + // ArtifactDataDefinition artifactDataDef = new + // ArtifactDataDefinition(); + artifactDataDef.setArtifactChecksum("YTg2Mjg4MWJhNmI5NzBiNzdDFkMWI="); + artifactDataDef.setArtifactName("create_myRoot.sh"); + artifactDataDef.setArtifactLabel("create_myRoot"); + artifactDataDef.setArtifactType("SHELL"); + artifactDataDef.setDescription("good description"); + artifactDataDef.setEsId("esId"); + artifactDataDef.setUniqueId(resultResource.getUniqueId() + "." + artifactDataDef.getArtifactLabel()); + artifactDef = new ArtifactDefinition(artifactDataDef, "UEsDBAoAAAAIAAeLb0bDQz"); + // artifacts.put("myArtifact", artifactDef); + // resource2.setArtifacts(artifacts); + + Either addArifactToResource = artifactOperation + .addArifactToComponent(artifactDef, resultResource.getUniqueId(), NodeTypeEnum.Resource, false, true); + assertTrue(addArifactToResource.isLeft()); + + Either resource = resourceOperation.getResource(resultResource.getUniqueId()); + assertTrue(resource.isLeft()); + + Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + String json = prettyGson.toJson(resource.left().value()); + log.debug(json); + return resource.left().value(); + } + + private void createCapabilityOnGraph(String capabilityTypeName) { + + CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(); + capabilityTypeDefinition.setDescription("desc1"); + capabilityTypeDefinition.setType(capabilityTypeName); + Map properties = new HashMap(); + String propName1 = "disk_size"; + PropertyDefinition property1 = buildProperty1(); + properties.put(propName1, property1); + capabilityTypeDefinition.setProperties(properties); + + Either addCapabilityType1 = capabilityTypeOperation + .addCapabilityType(capabilityTypeDefinition); + assertTrue(addCapabilityType1.isLeft()); + } + + private User convertUserDataToUser(UserData modifierData) { + User modifier = new User(); + modifier.setUserId(modifierData.getUserId()); + modifier.setEmail(modifierData.getEmail()); + modifier.setFirstName(modifierData.getFirstName()); + modifier.setLastName(modifierData.getLastName()); + modifier.setRole(modifierData.getRole()); + return modifier; + } + + private Resource buildResourceMetadata(String userId, String category) { + // deleteAndCreateCategory(category); + + Resource resource = new Resource(); + resource.setName("my-resource"); + resource.setVersion("1.0"); + ; + resource.setDescription("description 1"); + resource.setAbstract(false); + resource.setCreatorUserId(userId); + resource.setContactId("contactId@sdc.com"); + resource.setVendorName("vendor 1"); + resource.setVendorRelease("1.0.0"); + String[] categoryArr = category.split("/"); + resource.addCategory(categoryArr[0], categoryArr[1]); + resource.setIcon("images/my.png"); + List tags = new ArrayList(); + tags.add("TAG1"); + tags.add("TAG2"); + resource.setTags(tags); + return resource; + } + + public UserData deleteAndCreateUser(String userId, String firstName, String lastName, String role) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + userData.setRole(role); + + titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanGenericDao.createNode(userData, UserData.class); + titanGenericDao.commit(); + + return userData; + } + + private PropertyDefinition buildProperty1() { + PropertyDefinition property1 = new PropertyDefinition(); + property1.setDefaultValue("10"); + property1.setDescription( + "Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node."); + property1.setType(ToscaType.INTEGER.name().toLowerCase()); + List constraints = new ArrayList(); + GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0"); + constraints.add(propertyConstraint1); + + LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10"); + constraints.add(propertyConstraint2); + + property1.setConstraints(constraints); + return property1; + } + + private ArtifactDefinition addArtifactToService(String userId, String serviceId, String artifactName) { + ArtifactDefinition artifactInfo = new ArtifactDefinition(); + + artifactInfo.setArtifactName(artifactName + ".sh"); + artifactInfo.setArtifactType("SHELL"); + artifactInfo.setDescription("hdkfhskdfgh"); + artifactInfo.setPayloadData("UEsDBAoAAAAIAAeLb0bDQz"); + + artifactInfo.setUserIdCreator(userId); + String fullName = "Jim H"; + artifactInfo.setUpdaterFullName(fullName); + long time = System.currentTimeMillis(); + artifactInfo.setCreatorFullName(fullName); + artifactInfo.setCreationDate(time); + artifactInfo.setLastUpdateDate(time); + artifactInfo.setUserIdLastUpdater(userId); + artifactInfo.setArtifactLabel(artifactName); + artifactInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(serviceId, artifactInfo.getArtifactLabel())); + + Either artifact = artifactOperation + .addArifactToComponent(artifactInfo, serviceId, NodeTypeEnum.Service, true, true); + assertTrue(artifact.isLeft()); + return artifactInfo; + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperationTest.java new file mode 100644 index 0000000000..5bd6c831a5 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperationTest.java @@ -0,0 +1,120 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; + +import javax.annotation.Resource; + +import org.apache.commons.lang.StringUtils; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PolicyTypeOperation; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") + +public class PolicyTypeOperationTest extends ModelTestBase { + + @Resource(name = "policy-type-operation") + private PolicyTypeOperation policyTypeOperation; + + @BeforeClass + public static void setupBeforeClass() { + ModelTestBase.init(); + + } + + @Before + public void cleanUp() { + TitanGenericDao titanGenericDao = policyTypeOperation.titanGenericDao; + Either graphResult = titanGenericDao.getGraph(); + TitanGraph graph = graphResult.left().value(); + + Iterable vertices = graph.query().vertices(); + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + vertex.remove(); + } + + } + titanGenericDao.commit(); + } + + @Test + public void testAddPolicyType() { + + PolicyTypeDefinition policyTypePreCreate = createPolicyTypeDef(); + assertTrue(StringUtils.isEmpty(policyTypePreCreate.getUniqueId())); + Either addPolicyType = policyTypeOperation + .addPolicyType(policyTypePreCreate); + assertTrue(addPolicyType.isLeft()); + PolicyTypeDefinition policyTypePostCreate = addPolicyType.left().value(); + assertEquals(policyTypePostCreate.getType(), policyTypePreCreate.getType()); + assertEquals(policyTypePostCreate.getDescription(), policyTypePreCreate.getDescription()); + + assertTrue(!StringUtils.isEmpty(policyTypePostCreate.getUniqueId())); + } + + @Test + public void testGetLatestPolicyTypeByType() { + PolicyTypeDefinition policyTypeCreated = policyTypeOperation.addPolicyType(createPolicyTypeDef()).left() + .value(); + Either eitherPolicyTypeFetched = policyTypeOperation + .getLatestPolicyTypeByType(policyTypeCreated.getType()); + assertTrue(eitherPolicyTypeFetched.isLeft()); + PolicyTypeDefinition policyTypeFetched = eitherPolicyTypeFetched.left().value(); + assertEquals(policyTypeFetched.toString(), policyTypeCreated.toString()); + + } + + private PolicyTypeDefinition createPolicyTypeDef() { + PolicyTypeDataDefinition policyTypeDataDefinition = new PolicyTypeDataDefinition(); + policyTypeDataDefinition + .setDescription("description: The TOSCA Policy Type all other TOSCA Policy Types derive from"); + policyTypeDataDefinition.setType("tosca.policies.Root"); + PolicyTypeDefinition policyTypeDefinition = new PolicyTypeDefinition(policyTypeDataDefinition); + policyTypeDefinition.setHighestVersion(true); + policyTypeDefinition.setVersion("1.0"); + return policyTypeDefinition; + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperationTest.java new file mode 100644 index 0000000000..6caa3044ad --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperationTest.java @@ -0,0 +1,548 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.PropertyConstraint; +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.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint; +import org.openecomp.sdc.be.resources.data.PropertyData; + +import fj.data.Either; + +public class PropertyOperationTest extends ModelTestBase { + + PropertyOperation propertyOperation = new PropertyOperation(); + + TitanGenericDao titanGenericDao = Mockito.mock(TitanGenericDao.class); + + @Before + public void setup() { + propertyOperation.setTitanGenericDao(titanGenericDao); + + } + + /* + * @Test public void addPropertyToResourceTest() { + * + * String propName = "myProp"; PropertyDefinition property = + * buildPropertyDefinition(); List constraints = + * buildConstraints(); property.setConstraints(constraints); + * + * PropertyData propertyData = new PropertyData(property, + * propertyOperation.convertConstraintsToString(constraints)); + * + * Either either = + * Either.left(propertyData); + * //when(propertyDao.create((GraphNeighbourTable)anyObject(), + * eq(PropertyData.class), eq(NodeTypeEnum.Property))).thenReturn(either); + * GraphRelation graphRelation = new GraphRelation(); Either relationResult = Either.left(graphRelation); + * + * when(titanGenericDao.createNode((PropertyData)anyObject(), + * eq(PropertyData.class))).thenReturn(either); + * when(titanGenericDao.createRelation((GraphNode)anyObject(), + * (GraphNode)anyObject(), eq(GraphEdgeLabels.PROPERTY), + * anyMap())).thenReturn(relationResult); + * + * Either result = + * propertyOperation.addPropertyToResource(propName, property, + * NodeTypeEnum.Resource, "my-resource.1.0"); + * + * assertTrue(result.isLeft()); System.out.println(result.left().value()); + * PropertyDefinition propertyDefinition = result.left().value(); + * + * List originalConstraints = property.getConstraints(); + * List propertyConstraintsResult = + * propertyDefinition.getConstraints(); + * assertEquals(propertyConstraintsResult.size(), + * originalConstraints.size()); + * + * } + */ + private PropertyDefinition buildPropertyDefinition() { + PropertyDefinition property = new PropertyDefinition(); + property.setDefaultValue("10"); + property.setDescription( + "Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node."); + property.setType(ToscaType.INTEGER.name().toLowerCase()); + return property; + } + + @Test + public void addPropertiesToGraphTableTest() { + + // Map properties = new HashMap(); + // String propName = "myProp"; + // PropertyDefinition property = buildPropertyDefinition(); + // + // List constraints = buildConstraints(); + // property.setConstraints(constraints); + // + // properties.put(propName, property); + // + // GraphNeighbourTable graphNeighbourTable = new GraphNeighbourTable(); + // ResourceData resourceData = new ResourceData(); + // String resourceName = "my-resource"; + // String resourceVersion = "1.0"; + // String resourceId = resourceName + "." + resourceVersion; + // resourceData.setUniqueId(resourceId); + // int resourceIndex = graphNeighbourTable.addNode(resourceData); + // + // heatParametersOperation.addPropertiesToGraphTable(properties, + // graphNeighbourTable, resourceIndex, resourceId); + // + // assertEquals(2, graphNeighbourTable.getNodes().size()); + // assertEquals(1, graphNeighbourTable.getDirectedEdges().size()); + // List nodes = graphNeighbourTable.getNodes(); + // boolean nodeFound = false; + // for (GraphNode neo4jNode : nodes) { + // if (neo4jNode instanceof PropertyData) { + // PropertyData propertyData = (PropertyData)neo4jNode; + // assertEquals("check property unique id", resourceId + "." + propName, + // propertyData.getUniqueId()); + // assertEquals(property.getDescription(), + // propertyData.getPropertyDataDefinition().getDescription()); + // nodeFound = true; + // } + // } + // assertEquals("looking for PropertyData object in table", true, + // nodeFound); + // + // NodeRelation nodeRelation = + // graphNeighbourTable.getDirectedEdges().get(0); + // assertEquals("check from index to index edge", 0, + // nodeRelation.getFromIndex()); + // assertEquals("check from index to index edge", 1, + // nodeRelation.getToIndex()); + // assertEquals("check edge type", + // GraphEdgePropertiesDictionary.PROPERTY, + // nodeRelation.getEdge().getEdgeType()); + // assertEquals("check propert name on edge", true, + // nodeRelation.getEdge().getProperties().values().contains(propName)); + } + + @Test + public void convertConstraintsTest() { + + List constraints = buildConstraints(); + List convertedStringConstraints = propertyOperation.convertConstraintsToString(constraints); + assertEquals("constraints size", constraints.size(), convertedStringConstraints.size()); + + List convertedConstraints = propertyOperation + .convertConstraints(convertedStringConstraints); + assertEquals("check size of constraints", constraints.size(), convertedConstraints.size()); + + Set constraintsClasses = new HashSet(); + for (PropertyConstraint propertyConstraint : constraints) { + constraintsClasses.add(propertyConstraint.getClass().getName()); + } + + for (PropertyConstraint propertyConstraint : convertedConstraints) { + assertTrue("check all classes generated", + constraintsClasses.contains(propertyConstraint.getClass().getName())); + } + } + + @Test + public void testIsPropertyDefaultValueValid_NoDefault() { + PropertyDefinition property = new PropertyDefinition(); + property.setName("myProperty"); + property.setType(ToscaPropertyType.BOOLEAN.getType()); + assertTrue(propertyOperation.isPropertyDefaultValueValid(property, null)); + } + + @Test + public void testIsPropertyDefaultValueValid_ValidDefault() { + PropertyDefinition property = new PropertyDefinition(); + property.setName("myProperty"); + property.setType(ToscaPropertyType.INTEGER.getType()); + property.setDefaultValue("50"); + assertTrue(propertyOperation.isPropertyDefaultValueValid(property, null)); + } + + @Test + public void testIsPropertyDefaultValueValid_InvalidDefault() { + PropertyDefinition property = new PropertyDefinition(); + property.setName("myProperty"); + property.setType(ToscaPropertyType.BOOLEAN.getType()); + property.setDefaultValue("50"); + assertFalse(propertyOperation.isPropertyDefaultValueValid(property, null)); + } + + private List buildConstraints() { + List constraints = new ArrayList(); + GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0"); + LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10"); + List range = new ArrayList(); + range.add("0"); + range.add("100"); + InRangeConstraint propertyConstraint3 = new InRangeConstraint(range); + constraints.add(propertyConstraint1); + constraints.add(propertyConstraint2); + constraints.add(propertyConstraint3); + return constraints; + } + + @Test + public void findPropertyValueBestMatch1() { + + String propertyUniqueId = "x1"; + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(); + instanceProperty.setValue("v1"); + instanceProperty.setDefaultValue("vv1"); + List path = new ArrayList<>(); + path.add("node1"); + path.add("node2"); + path.add("node3"); + instanceProperty.setPath(path); + + Map instanceIdToValue = new HashMap(); + ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty(); + instanceProperty1.setValue("v1node1"); + instanceIdToValue.put("node1", instanceProperty1); + + ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty(); + instanceProperty2.setValue("v1node2"); + instanceIdToValue.put("node2", instanceProperty2); + + ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty(); + instanceProperty3.setValue("v1node3"); + instanceIdToValue.put("node3", instanceProperty3); + + propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + assertEquals("check value", "v1node1", instanceProperty.getValue()); + assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue()); + + } + + @Test + public void findPropertyValueBestMatch2() { + + String propertyUniqueId = "x1"; + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(); + instanceProperty.setValue("v1"); + instanceProperty.setDefaultValue("vv1"); + List path = new ArrayList<>(); + path.add("node1"); + path.add("node2"); + path.add("node3"); + instanceProperty.setPath(path); + + Map instanceIdToValue = new HashMap(); + + ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty(); + instanceProperty2.setValue("v1node2"); + instanceProperty2.setValueUniqueUid("aaaa"); + instanceIdToValue.put("node2", instanceProperty2); + + propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + assertEquals("check value", "v1node2", instanceProperty.getValue()); + assertEquals("check default value", "vv1", instanceProperty.getDefaultValue()); + assertNull("check value unique id is null", instanceProperty.getValueUniqueUid()); + + } + + @Test + public void findPropertyValueBestMatch3() { + + String propertyUniqueId = "x1"; + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(); + instanceProperty.setValue("v1"); + instanceProperty.setDefaultValue("vv1"); + List path = new ArrayList<>(); + path.add("node1"); + path.add("node2"); + path.add("node3"); + instanceProperty.setPath(path); + + Map instanceIdToValue = new HashMap(); + ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty(); + instanceProperty1.setValue("v1node1"); + instanceProperty1.setValueUniqueUid("aaaa"); + instanceIdToValue.put("node1", instanceProperty1); + + ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty(); + instanceProperty3.setValue("v1node3"); + instanceIdToValue.put("node3", instanceProperty3); + + propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + assertEquals("check value", "v1node1", instanceProperty.getValue()); + assertEquals("check default value", "v1node3", instanceProperty.getDefaultValue()); + assertEquals("check valid unique id", instanceProperty1.getValueUniqueUid(), + instanceProperty.getValueUniqueUid()); + + } + + @Test + public void findPropertyValueBestMatch1Rules() { + + String propertyUniqueId = "x1"; + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(); + instanceProperty.setValue("v1"); + instanceProperty.setDefaultValue("vv1"); + List path = new ArrayList<>(); + path.add("node1"); + path.add("node2"); + path.add("node3"); + instanceProperty.setPath(path); + + Map instanceIdToValue = new HashMap(); + ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty(); + instanceProperty1.setValue("v1node1"); + + List rules = new ArrayList<>(); + PropertyRule propertyRule = new PropertyRule(); + String[] ruleArr = { "node1", ".+", "node3" }; + List rule1 = new ArrayList<>(Arrays.asList(ruleArr)); + propertyRule.setRule(rule1); + propertyRule.setValue("88"); + rules.add(propertyRule); + instanceProperty1.setRules(rules); + + instanceIdToValue.put("node1", instanceProperty1); + + ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty(); + instanceProperty2.setValue("v1node2"); + instanceIdToValue.put("node2", instanceProperty2); + + ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty(); + instanceProperty3.setValue("v1node3"); + instanceIdToValue.put("node3", instanceProperty3); + + propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + assertEquals("check value", propertyRule.getValue(), instanceProperty.getValue()); + assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue()); + + } + + @Test + public void findPropertyValueBestMatch2Rules() { + + String propertyUniqueId = "x1"; + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(); + instanceProperty.setValue("v1"); + instanceProperty.setDefaultValue("vv1"); + List path = new ArrayList<>(); + path.add("node1"); + path.add("node2"); + path.add("node3"); + instanceProperty.setPath(path); + + Map instanceIdToValue = new HashMap(); + ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty(); + instanceProperty1.setValue("v1node1"); + + List rules = new ArrayList<>(); + PropertyRule propertyRule1 = new PropertyRule(); + String[] ruleArr1 = { "node1", "node2", ".+" }; + List rule1 = new ArrayList<>(Arrays.asList(ruleArr1)); + propertyRule1.setRule(rule1); + propertyRule1.setValue("88"); + + PropertyRule propertyRule2 = new PropertyRule(); + String[] ruleArr2 = { "node1", "node2", "node3" }; + List rule2 = new ArrayList<>(Arrays.asList(ruleArr2)); + propertyRule2.setRule(rule2); + propertyRule2.setValue("99"); + + rules.add(propertyRule2); + rules.add(propertyRule1); + + instanceProperty1.setRules(rules); + + instanceIdToValue.put("node1", instanceProperty1); + + ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty(); + instanceProperty2.setValue("v1node2"); + instanceIdToValue.put("node2", instanceProperty2); + + ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty(); + instanceProperty3.setValue("v1node3"); + instanceIdToValue.put("node3", instanceProperty3); + + propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue()); + assertEquals("check default value", "v1node2", instanceProperty.getDefaultValue()); + + } + + @Test + public void findPropertyValueBestMatch1RuleLowLevel() { + + String propertyUniqueId = "x1"; + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(); + instanceProperty.setValue("v1"); + instanceProperty.setDefaultValue("vv1"); + List path = new ArrayList<>(); + path.add("node1"); + path.add("node2"); + path.add("node3"); + instanceProperty.setPath(path); + + Map instanceIdToValue = new HashMap(); + ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty(); + instanceProperty1.setValue("v1node1"); + + List rules = new ArrayList<>(); + PropertyRule propertyRule1 = new PropertyRule(); + String[] ruleArr1 = { "node1", "node2", ".+" }; + List rule1 = new ArrayList<>(Arrays.asList(ruleArr1)); + propertyRule1.setRule(rule1); + propertyRule1.setValue("88"); + + PropertyRule propertyRule2 = new PropertyRule(); + String[] ruleArr2 = { "node1", "node2", "node3" }; + List rule2 = new ArrayList<>(Arrays.asList(ruleArr2)); + propertyRule2.setRule(rule2); + propertyRule2.setValue("99"); + + rules.add(propertyRule2); + rules.add(propertyRule1); + + instanceProperty1.setRules(rules); + + instanceIdToValue.put("node1", instanceProperty1); + + ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty(); + instanceProperty2.setValue("v1node2"); + + List rules3 = new ArrayList<>(); + PropertyRule propertyRule3 = new PropertyRule(); + String[] ruleArr3 = { "node2", "node3" }; + List rule3 = new ArrayList<>(Arrays.asList(ruleArr3)); + propertyRule3.setRule(rule3); + propertyRule3.setValue("77"); + rules3.add(propertyRule3); + + instanceProperty2.setRules(rules3); + instanceIdToValue.put("node2", instanceProperty2); + + ComponentInstanceProperty instanceProperty3 = new ComponentInstanceProperty(); + instanceProperty3.setValue("v1node3"); + instanceIdToValue.put("node3", instanceProperty3); + + propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue()); + assertEquals("check default value", propertyRule3.getValue(), instanceProperty.getDefaultValue()); + + } + + @Test + public void findPropertyValueBestMatchDefaultValueNotChanged() { + + String propertyUniqueId = "x1"; + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(); + instanceProperty.setValue("v1"); + instanceProperty.setDefaultValue("vv1"); + List path = new ArrayList<>(); + path.add("node1"); + path.add("node2"); + path.add("node3"); + instanceProperty.setPath(path); + + Map instanceIdToValue = new HashMap(); + ComponentInstanceProperty instanceProperty1 = new ComponentInstanceProperty(); + instanceProperty1.setValue("v1node1"); + + List rules = new ArrayList<>(); + PropertyRule propertyRule1 = new PropertyRule(); + String[] ruleArr1 = { "node1", "node2", ".+" }; + List rule1 = new ArrayList<>(Arrays.asList(ruleArr1)); + propertyRule1.setRule(rule1); + propertyRule1.setValue("88"); + + PropertyRule propertyRule2 = new PropertyRule(); + String[] ruleArr2 = { "node1", "node2", "node3" }; + List rule2 = new ArrayList<>(Arrays.asList(ruleArr2)); + propertyRule2.setRule(rule2); + propertyRule2.setValue("99"); + + rules.add(propertyRule2); + rules.add(propertyRule1); + + instanceProperty1.setRules(rules); + + instanceIdToValue.put("node1", instanceProperty1); + + ComponentInstanceProperty instanceProperty2 = new ComponentInstanceProperty(); + instanceProperty2.setValue("v1node2"); + + List rules3 = new ArrayList<>(); + PropertyRule propertyRule3 = new PropertyRule(); + String[] ruleArr3 = { "node2", "node333" }; + List rule3 = new ArrayList<>(Arrays.asList(ruleArr3)); + propertyRule3.setRule(rule3); + propertyRule3.setValue("77"); + rules3.add(propertyRule3); + + instanceProperty2.setRules(rules3); + instanceIdToValue.put("node2", instanceProperty2); + + propertyOperation.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + assertEquals("check value", propertyRule2.getValue(), instanceProperty.getValue()); + assertEquals("check default value", "vv1", instanceProperty.getDefaultValue()); + + } + + // add all rule types + // add rule with size = 1(instance itself = ALL). relevant for VLi. equals + // to X.*.*.* in all paths size +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperationTest.java new file mode 100644 index 0000000000..fe4b501148 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperationTest.java @@ -0,0 +1,236 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +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.CapabilityDefinition; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.CapabiltyInstance; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.RequirementImplDef; +import org.openecomp.sdc.be.model.Resource; +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.CapabilityTypeOperation; +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.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.impl.util.OperationTestsUtil; +import org.openecomp.sdc.be.model.operations.impl.util.PrintGraph; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.common.api.ConfigurationListener; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class RequirementOperationTest extends ModelTestBase { + private static Logger log = LoggerFactory.getLogger(RequirementOperationTest.class.getName()); + private Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + + private static String USER_ID = "muserId"; + private static String CATEGORY_NAME = "category/mycategory"; + + private static ConfigurationManager configurationManager; + + @javax.annotation.Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + @javax.annotation.Resource(name = "requirement-operation") + private RequirementOperation requirementOperation; + + @javax.annotation.Resource(name = "resource-operation") + private ResourceOperation resourceOperation; + + @javax.annotation.Resource(name = "property-operation") + private PropertyOperation propertyOperation; + + @javax.annotation.Resource(name = "capability-operation") + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource(name = "capability-type-operation") + private CapabilityTypeOperation capabilityTypeOperation; + + @BeforeClass + public static void setupBeforeClass() { + + // configurationManager = new ConfigurationManager( + // new ConfigurationSource() { + // + // @Override + // public T getAndWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public void addWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // + // } + // }); + // + // Configuration configuration = new Configuration(); + // configuration.setTitanInMemoryGraph(true); + // + // configurationManager.setConfiguration(configuration); + ModelTestBase.init(); + } + + @Test + public void testDummy() { + + assertTrue(requirementOperation != null); + + } + + @Test + public void testAddRequirementNotExistCapability() { + + String reqName = "host"; + RequirementDefinition reqDefinition = new RequirementDefinition(); + reqDefinition.setNode("tosca.nodes.Compute"); + reqDefinition.setRelationship("myrelationship"); + reqDefinition.setCapability("mycapability___2"); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", "0.1", null, + true, true); + + Either addRequirementToResource = requirementOperation + .addRequirementToResource(reqName, reqDefinition, resource.getUniqueId()); + assertEquals("check error", StorageOperationStatus.INVALID_ID, addRequirementToResource.right().value()); + + } + + @Before + public void createUserAndCategory() { + String[] category = CATEGORY_NAME.split("/"); + OperationTestsUtil.deleteAndCreateResourceCategory(category[0], category[1], titanDao); + deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID); + } + + private UserData deleteAndCreateUser(String userId, String firstName, String lastName) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + + titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanDao.createNode(userData, UserData.class); + titanDao.commit(); + + return userData; + } + + @Test + public void testAddRequirementWithCapability() { + + String capabilityTypeName = "tosca.nodes.Container"; + + String reqName = "host"; + RequirementDefinition reqDefinition = new RequirementDefinition(); + reqDefinition.setNode("tosca.nodes.Compute"); + reqDefinition.setRelationship("myrelationship"); + reqDefinition.setCapability(capabilityTypeName); + + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + + capabilityTypeOperationTest.createCapability(capabilityTypeName); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", "2.0", null, + true, true); + + Either addRequirementToResource = requirementOperation + .addRequirementToResource(reqName, reqDefinition, resource.getUniqueId()); + + assertEquals("check requirement was added", true, addRequirementToResource.isLeft()); + + Either resource2 = resourceOperation.getResource(resource.getUniqueId()); + String json = prettyGson.toJson(resource2); + log.debug(json); + } + + private void compareProperties(Map capabilityProperties, + CapabiltyInstance capabiltyInstance, Map actual) { + + Map properties = capabiltyInstance.getProperties(); + + for (Entry entry : capabilityProperties.entrySet()) { + String paramName = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + String defaultValue = propertyDefinition.getDefaultValue(); + + String value = properties.get(paramName); + + String actualValue = null; + if (actual != null) { + actualValue = actual.get(paramName); + } + if (actualValue != null) { + assertEquals("check property value of key " + paramName, value, actualValue); + } else { + assertEquals("check property value of key " + paramName, value, defaultValue); + } + } + + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ResourceInstanceOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ResourceInstanceOperationTest.java new file mode 100644 index 0000000000..bef51f415c --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ResourceInstanceOperationTest.java @@ -0,0 +1,2511 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +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.enums.NodeTypeEnum; +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.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +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.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ArtifactOperation; +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.HeatParametersOperation; +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.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.impl.util.OperationTestsUtil; +import org.openecomp.sdc.be.model.operations.impl.util.PrintGraph; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.HeatParameterData; +import org.openecomp.sdc.be.resources.data.HeatParameterValueData; +import org.openecomp.sdc.be.resources.data.RelationshipInstData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class ResourceInstanceOperationTest extends ModelTestBase { + private static Logger log = LoggerFactory.getLogger(ResourceInstanceOperationTest.class.getName()); + private Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + + private static String USER_ID = "muserId"; + private static String CATEGORY_NAME = "category/mycategory"; + + @javax.annotation.Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + @javax.annotation.Resource(name = "requirement-operation") + private RequirementOperation requirementOperation; + + @javax.annotation.Resource(name = "resource-operation") + private ResourceOperation resourceOperation; + + @javax.annotation.Resource(name = "property-operation") + private PropertyOperation propertyOperation; + + @javax.annotation.Resource(name = "capability-operation") + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource(name = "capability-type-operation") + private CapabilityTypeOperation capabilityTypeOperation; + + @javax.annotation.Resource(name = "component-instance-operation") + private ComponentInstanceOperation resourceInstanceOperation; + + @javax.annotation.Resource + private HeatParametersOperation heatParameterOperation; + + @javax.annotation.Resource + private ArtifactOperation artifactOperation; + + private String CAPABILITY_1 = "mycapability101"; + private String CAPABILITY_2 = "mycapability102"; + + private Integer TEST_CLASS_NUMBER = 1; + + public final static Pattern COMPONENT_NAME_DELIMETER_PATTERN = Pattern.compile("[\\.\\-\\_]+"); + + public final static Pattern COMPONENT_INCTANCE_NAME_DELIMETER_PATTERN = Pattern.compile("[\\.\\-\\_]+"); + + @BeforeClass + public static void setupBeforeClass() { + + // configurationManager = new ConfigurationManager( + // new ConfigurationSource() { + // + // @Override + // public T getAndWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public void addWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // + // } + // }); + // + // Configuration configuration = new Configuration(); + // + // ////inmemory + // boolean useInMemory = true; + // if (useInMemory) { + // configuration.setTitanInMemoryGraph(true); + // } else { + // configuration.setTitanInMemoryGraph(false); + // configuration.setTitanCfgFile("C:\\Git_work\\D2-SDnC\\catalog-be\\src\\main\\resources\\config\\titan.properties"); + // } + // + // + // + // configurationManager.setConfiguration(configuration); + ModelTestBase.init(); + } + + public void setOperations(TitanGenericDao titanDao, CapabilityTypeOperation capabilityTypeOperation, + RequirementOperation requirementOperation, CapabilityOperation capabilityOperation, + ResourceOperation resourceOperation, PropertyOperation propertyOperation, + ComponentInstanceOperation resourceInstanceOperation2) { + this.titanDao = titanDao; + this.capabilityTypeOperation = capabilityTypeOperation; + this.capabilityOperation = capabilityOperation; + this.requirementOperation = requirementOperation; + this.resourceOperation = resourceOperation; + this.propertyOperation = propertyOperation; + this.resourceInstanceOperation = resourceInstanceOperation2; + } + + @Test + public void testDummy() { + + assertTrue(requirementOperation != null); + + } + + @Test + public void testAddResourceInstanceInvalidServiceId() { + + try { + ComponentInstance instance = buildResourceInstance("tosca.nodes.Apache.2.0", "1", "tosca.nodes.Apache"); + + Either status = resourceInstanceOperation + .addComponentInstanceToContainerComponent("service1", NodeTypeEnum.Service, "1", true, instance, + NodeTypeEnum.Resource, false); + assertEquals("check failed status - service is not in graph", true, status.isRight()); + assertEquals("check failed status value - service is not in graph", TitanOperationStatus.INVALID_ID, + status.right().value()); + } finally { + titanDao.rollback(); + } + + } + + @Test + public void testAddResourceInstanceValidServiceIdInvalidResourceId() { + try { + + ServiceMetadataData serviceData1 = createService("myservice1.1.0"); + + ComponentInstance instance = buildResourceInstance("tosca.nodes.Apache.2.0", "1", "tosca.nodes.Apache"); + + Either status = resourceInstanceOperation + .addComponentInstanceToContainerComponent((String) serviceData1.getUniqueId(), NodeTypeEnum.Service, + "1", true, instance, NodeTypeEnum.Resource, false); + + assertEquals("check failed status - service is not in graph", true, status.isRight()); + assertEquals("check failed status value - service is not in graph", TitanOperationStatus.INVALID_ID, + status.right().value()); + + } finally { + titanDao.rollback(); + } + + } + + @Test + public void testAddResourceInstanceValidServiceId() { + try { + String serviceName = "myservice1.1.0"; + String resourceName = "tosca.nodes.Apache.2.0"; + ServiceMetadataData serviceData1 = createService(serviceName); + ResourceMetadataData resourceData = createResource(resourceName); + + ComponentInstance instance = buildResourceInstance(resourceData.getMetadataDataDefinition().getUniqueId(), + "1", "tosca.nodes.Apache"); + + Either status = resourceInstanceOperation + .addComponentInstanceToContainerComponent((String) serviceData1.getUniqueId(), NodeTypeEnum.Service, + "1", true, instance, NodeTypeEnum.Resource, false); + + assertEquals("check success status - service is not in graph", true, status.isLeft()); + + ComponentInstance value = status.left().value(); + assertEquals("check name exists", "tosca.nodes.Apache 1", value.getName()); + + ServiceMetadataData serviceData2 = deleteService(serviceName); + ResourceMetadataData resourceData2 = deleteResource(resourceName); + + } finally { + titanDao.rollback(); + } + } + + @Test + public void testUpdateResourceInstance() { + try { + String serviceName = "myservice1.1.0"; + String resourceName = "tosca.nodes.Apache.2.0"; + ServiceMetadataData serviceData1 = createService(serviceName); + ResourceMetadataData resourceData = createResource(resourceName); + + ComponentInstance instance = buildResourceInstance(resourceData.getMetadataDataDefinition().getUniqueId(), + "1", "tosca.nodes.Apache"); + + Either status = resourceInstanceOperation + .addComponentInstanceToContainerComponent((String) serviceData1.getUniqueId(), NodeTypeEnum.Service, + "1", true, instance, NodeTypeEnum.Resource, false); + + ComponentInstance resourceInstance = status.left().value(); + Long creationTime = resourceInstance.getCreationTime(); + String name = resourceInstance.getName(); + assertEquals("check success status - service is not in graph", true, status.isLeft()); + + ComponentInstance value = status.left().value(); + assertEquals("check name exists", "tosca.nodes.Apache 1", value.getName()); + + Either u1Res = resourceInstanceOperation.updateResourceInstance( + (String) serviceData1.getUniqueId(), NodeTypeEnum.Service, resourceInstance.getUniqueId(), value, + true); + assertTrue("check update succeed", u1Res.isLeft()); + + Long lastModificationTimeNC = value.getModificationTime(); + String desc = "AAAAA"; + String posX = "15"; + String posY = "12"; + String updatedName = "Shlokshlik"; + value.setDescription(desc); + value.setPosX(posX); + Either u2Res = resourceInstanceOperation.updateResourceInstance( + (String) serviceData1.getUniqueId(), NodeTypeEnum.Service, resourceInstance.getUniqueId(), value, + true); + assertTrue("check update succeed", u2Res.isLeft()); + assertEquals("check resource instance updated", desc, u2Res.left().value().getDescription()); + assertEquals("check resource instance updated", posX, u2Res.left().value().getPosX()); + assertEquals("check resource instance updated", resourceInstance.getPosY(), u2Res.left().value().getPosY()); + assertEquals("check modification time was not updated since it was supplied", + u2Res.left().value().getModificationTime(), lastModificationTimeNC); + + Long lastModificationTime = value.getModificationTime(); + value.setPosY(posY); + value.setModificationTime(null); + value.setName(updatedName); + Either u3Res = resourceInstanceOperation.updateResourceInstance( + (String) serviceData1.getUniqueId(), NodeTypeEnum.Service, resourceInstance.getUniqueId(), value, + true); + assertTrue("check update succeed", u3Res.isLeft()); + assertEquals("check resource instance updated", desc, u3Res.left().value().getDescription()); + assertEquals("check resource pos x updated", posX, u3Res.left().value().getPosX()); + assertEquals("check resource pos y updated", posY, u3Res.left().value().getPosY()); + assertTrue("check modification time was updated", + u3Res.left().value().getModificationTime() >= lastModificationTime); + assertEquals("check creation time was not updated", creationTime, u3Res.left().value().getCreationTime()); + assertEquals("check name was updated", updatedName, u3Res.left().value().getName()); + + ServiceMetadataData serviceData2 = deleteService(serviceName); + ResourceMetadataData resourceData2 = deleteResource(resourceName); + + } finally { + titanDao.rollback(); + } + } + + @Test + public void testRemoveResourceInstance() { + try { + String serviceName = "myservice1.1.0"; + String resourceName = "tosca.nodes.Apache.2.0"; + ServiceMetadataData serviceData1 = createService(serviceName); + ResourceMetadataData resourceData = createResource(resourceName); + + ComponentInstance instance = buildResourceInstance(resourceData.getMetadataDataDefinition().getUniqueId(), + "1", "tosca.nodes.Apache"); + + Either status = resourceInstanceOperation + .addComponentInstanceToContainerComponent((String) serviceData1.getUniqueId(), NodeTypeEnum.Service, + "1", true, instance, NodeTypeEnum.Resource, false); + + assertEquals("check success status - service is not in graph", true, status.isLeft()); + + ComponentInstance value = status.left().value(); + assertEquals("check name exists", "tosca.nodes.Apache 1", value.getName()); + + Either status1 = resourceInstanceOperation + .removeComponentInstanceFromComponent(NodeTypeEnum.Service, serviceName, value.getUniqueId()); + + assertTrue("check resource service was deleted.", status1.isLeft()); + assertEquals("check resource instance returned.", "tosca.nodes.Apache 1", status1.left().value().getName()); + + ServiceMetadataData serviceData2 = deleteService(serviceName); + ResourceMetadataData resourceData2 = deleteResource(resourceName); + + } finally { + titanDao.rollback(); + } + } + + @Test + public void testRemoveResourceInstanceNotFound() { + try { + String serviceName = "myservice1.1.0"; + ServiceMetadataData serviceData1 = createService(serviceName); + + Either status1 = resourceInstanceOperation + .removeComponentInstanceFromComponent(NodeTypeEnum.Service, serviceName, "stam"); + + assertTrue("check resource service was not deleted.", status1.isRight()); + assertEquals("check NOT_FOUND returned.", TitanOperationStatus.NOT_FOUND, status1.right().value()); + + ServiceMetadataData serviceData2 = deleteService(serviceName); + + } finally { + titanDao.rollback(); + } + } + + public ServiceMetadataData createService(String serviceName) { + + ServiceMetadataData serviceData1 = new ServiceMetadataData(); + serviceData1.getMetadataDataDefinition().setUniqueId(serviceName); + Either createNode = titanDao.createNode(serviceData1, + ServiceMetadataData.class); + + assertTrue("check service created", createNode.isLeft()); + return createNode.left().value(); + } + + public ServiceMetadataData deleteService(String serviceName) { + + ServiceMetadataData serviceData1 = new ServiceMetadataData(); + serviceData1.getMetadataDataDefinition().setUniqueId(serviceName); + Either createNode = titanDao.deleteNode(serviceData1, + ServiceMetadataData.class); + assertTrue("check service deleted", createNode.isLeft()); + return createNode.left().value(); + } + + public ResourceMetadataData createResource(String resourceName) { + + ResourceMetadataData serviceData1 = new ResourceMetadataData(); + serviceData1.getMetadataDataDefinition().setUniqueId(resourceName); + Either createNode = titanDao.createNode(serviceData1, + ResourceMetadataData.class); + + assertTrue("check service created", createNode.isLeft()); + return createNode.left().value(); + } + + public ResourceMetadataData deleteResource(String resourceName) { + + ResourceMetadataData serviceData1 = new ResourceMetadataData(); + serviceData1.getMetadataDataDefinition().setUniqueId(resourceName); + Either createNode = titanDao.deleteNode(serviceData1, + ResourceMetadataData.class); + + assertTrue("check service created", createNode.isLeft()); + return createNode.left().value(); + } + + @Test + public void testAddResourceInstanceJson() { + addResourceInstanceJson(); + } + + public ComponentInstance addResourceInstanceJson() { + + ComponentInstance resourceInstance = buildResourceInstance("tosca.nodes.Apache.2.0", "1", "tosca.nodes.Apache"); + + String json = prettyGson.toJson(resourceInstance); + log.debug(json); + + return resourceInstance; + + } + + private ComponentInstance buildResourceInstance(String respurceUid, String instanceNumber, String name) { + ComponentInstance resourceInstance = new ComponentInstance(); + // resourceInstance + // .setUniqueId(".tosca.nodes.Apache.2.0." + instanceNumber); + resourceInstance.setName(name); + resourceInstance.setDescription("desc1"); + resourceInstance.setPosX("20"); + resourceInstance.setPosY("40"); + resourceInstance.setComponentUid(respurceUid); + resourceInstance.setCreationTime(System.currentTimeMillis()); + resourceInstance.setModificationTime(System.currentTimeMillis()); + resourceInstance.setNormalizedName(normaliseComponentName(name)); + + // Map requirements = new HashMap(); + // + // RequirementInstance requirementInstance1 = new RequirementInstance(); + // requirementInstance1.setNode("NA"); + // RelationshipImpl relationshipImpl = new RelationshipImpl(); + // relationshipImpl.setType("tosca.relationships.HostedOn"); + // requirementInstance1.setRelationship(relationshipImpl); + // + // requirements.put("host", requirementInstance1); + // + // RequirementInstance requirementInstance2 = new RequirementInstance(); + // requirementInstance2.setNode("NA"); + // RelationshipImpl relationshipImpl2 = new RelationshipImpl(); + // relationshipImpl2.setType("tosca.relationships.LinkTo"); + // requirementInstance2.setRelationship(relationshipImpl2); + // + // requirements.put("link", requirementInstance2); + // + // resourceInstance.setRequirements(requirements); + return resourceInstance; + } + + @Test + public void testConenctResourceInstancesJson() { + RequirementCapabilityRelDef addRelationship = addRelationship("apache_1", "compute_100"); + String json = prettyGson.toJson(addRelationship); + log.debug(json); + + RequirementCapabilityRelDef capabilityRelDef = prettyGson.fromJson(json, RequirementCapabilityRelDef.class); + log.debug("{}", capabilityRelDef); + + } + + public RequirementCapabilityRelDef addRelationship(String from, String to) { + RequirementCapabilityRelDef requirementCapabilityRelDef = new RequirementCapabilityRelDef(); + requirementCapabilityRelDef.setFromNode(from); + requirementCapabilityRelDef.setToNode(to); + List relationships = new ArrayList(); + + String req = "host"; + RelationshipImpl relationshipImpl = new RelationshipImpl(); + relationshipImpl.setType("tosca.nodes.HostedOn"); + RequirementAndRelationshipPair rels = new RequirementAndRelationshipPair(req, relationshipImpl); + relationships.add(rels); + + requirementCapabilityRelDef.setRelationships(relationships); + + return requirementCapabilityRelDef; + } + + @Before + public void createUserAndCategory() { + deleteAndCreateCategory(CATEGORY_NAME); + deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID); + } + + private UserData deleteAndCreateUser(String userId, String firstName, String lastName) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + + titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanDao.createNode(userData, UserData.class); + titanDao.commit(); + + return userData; + } + + private void deleteAndCreateCategory(String category) { + String[] names = category.split("/"); + OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao); + OperationTestsUtil.deleteAndCreateServiceCategory(category, titanDao); + + /* + * CategoryData categoryData = new CategoryData(); + * categoryData.setName(category); + * + * titanDao.deleteNode(categoryData, CategoryData.class); + * Either createNode = titanDao + * .createNode(categoryData, CategoryData.class); + * System.out.println("after creating caetgory " + createNode); + */ + } + + @Test + @Ignore + public void testConnectResourceInstances() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + try { + + String capabilityTypeName = CAPABILITY_2; + String reqName = "host"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef = capabilityTypeOperationTest + .createCapability(capabilityTypeName); + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + // create compute component + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, + "1.0", rootResource.getName(), true, true); + + // rollbackAndPrint(); + + // Add capabilities to Compute Resource + CapabilityDefinition addCapability = addCapabilityToResource(capabilityTypeName, "host", computeComponent); + + // CapabilityDefinition capabilityDefinition = new + // CapabilityDefinition(); + // capabilityDefinition.setDescription("my capability"); + // capabilityDefinition.setType(capabilityTypeName); + // List validSourceTypes = new ArrayList(); + // validSourceTypes.add("tosca.nodes.SC"); + // capabilityDefinition.setValidSourceTypes(validSourceTypes); + // Either + // addCapability = capabilityOperation + // .addCapability(computeComponent.getUniqueId(), "host", + // capabilityDefinition, true); + // //logger.debug("addCapability result " + addCapability); + // assertTrue("check capability created ", addCapability.isLeft()); + // + // ============================================= + + // create requirement definition + + Either addRequirementToResource = addRequirementToResource( + capabilityTypeName, reqName, reqNodeName, reqRelationship, softwareComponent); + + String parentReqUniqId = addRequirementToResource.left().value().getUniqueId(); + + // create my resource derived from software component + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", + myResourceVersion, softwareComponent.getName(), true, true); + + String serviceName = "myservice.1.0"; + List resInstances = buildServiceAndConnectBetweenResourceInstances(serviceName, resource, + computeComponent, "host", false, addCapability.getUniqueId(), + addRequirementToResource.left().value().getUniqueId()); + + PrintGraph printGraph = new PrintGraph(); + String webGraph = printGraph.buildGraphForWebgraphWiz(titanDao.getGraph().left().value()); + log.debug(webGraph); + + Either resourceFull = resourceOperation + .getResource(resource.getUniqueId()); + assertTrue(resourceFull.isLeft()); + List componentInstancesRelations = resourceFull.left().value() + .getComponentInstancesRelations(); + + RequirementCapabilityRelDef capabilityRelDef = componentInstancesRelations.get(0); + capabilityRelDef.getRelationships().get(0).setRequirement("host"); + + // disconnectResourcesInService(serviceName, resInstances.get(0), + // "host"); + disconnectResourcesInService(serviceName, capabilityRelDef); + + } finally { + rollbackAndPrint(false); + compareGraphSize(numberOfVertices); + } + + } + + @Test + @Ignore + public void testConnectResourceInstances1Requirement2Capabilities() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + + try { + + String capabilityTypeName1 = CAPABILITY_1; + String capabilityTypeName2 = CAPABILITY_2; + String reqName1 = "host1"; + String reqName2 = "host2"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef1 = capabilityTypeOperationTest + .createCapability(capabilityTypeName1); + CapabilityTypeDefinition createCapabilityDef2 = capabilityTypeOperationTest + .createCapability(capabilityTypeName2); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + // create compute component + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, + "1.0", rootResource.getName(), true, true); + + // Add capabilities to Compute Resource + CapabilityDefinition capabilty1 = addCapabilityToResource(capabilityTypeName1, reqName1, computeComponent); + CapabilityDefinition capabilty2 = addCapabilityToResource(capabilityTypeName2, reqName2, computeComponent); + + // rollbackAndPrint(); + + // create requirement definition + + Either addRequirementToResource = addRequirementToResource( + capabilityTypeName1, reqName1, reqNodeName, reqRelationship, softwareComponent); + + String requirementId = addRequirementToResource.left().value().getUniqueId(); + String parentReqUniqId = requirementId; + + // create my resource derived from software component + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", + myResourceVersion, softwareComponent.getName(), true, true); + + String serviceName = "myservice.1.0"; + List resInstances = buildServiceAndConnectBetweenResourceInstances(serviceName, resource, + computeComponent, reqName1, false, capabilty1.getUniqueId(), requirementId); + + PrintGraph printGraph = new PrintGraph(); + String webGraph = printGraph.buildGraphForWebgraphWiz(titanDao.getGraph().left().value()); + log.debug(webGraph); + + RequirementAndRelationshipPair relationPair = new RequirementAndRelationshipPair(); + relationPair.setRequirement(reqName2); + + relationPair.setCapabilityUid(capabilty1.getUniqueId()); + relationPair.setRequirementUid(requirementId); + + Either connectResourcesInService1 = resourceInstanceOperation + .connectResourcesInService(serviceName, NodeTypeEnum.Service, resInstances.get(0).getUniqueId(), + resInstances.get(1).getUniqueId(), relationPair); + assertEquals("check cannot associate resource instances", TitanOperationStatus.ILLEGAL_ARGUMENT, + connectResourcesInService1.right().value()); + relationPair.setRequirement(reqName1); + Either connectResourcesInService2 = resourceInstanceOperation + .connectResourcesInService(serviceName, NodeTypeEnum.Service, resInstances.get(0).getUniqueId(), + resInstances.get(1).getUniqueId(), relationPair); + assertEquals("check cannot associate resource instances", TitanOperationStatus.TITAN_SCHEMA_VIOLATION, + connectResourcesInService2.right().value()); + + relationPair.setRequirement(reqName1); + + RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef(); + capabilityRelDef.setFromNode(resInstances.get(0).getUniqueId()); + capabilityRelDef.setToNode(resInstances.get(1).getUniqueId()); + List list = new ArrayList<>(); + list.add(relationPair); + + disconnectResourcesInService(serviceName, capabilityRelDef); + + } finally { + rollbackAndPrint(); + compareGraphSize(numberOfVertices); + } + + } + + private void rollbackAndPrint() { + rollbackAndPrint(false); + } + + private void rollbackAndPrint(boolean print) { + TitanOperationStatus rollback = titanDao.rollback(); + if (print) { + log.debug("rollback status={}", rollback); + PrintGraph printGraph = new PrintGraph(); + printGraph.printGraphVertices(titanDao.getGraph().left().value()); + } + } + + @Test + public void testConnectResourceInstances2Requirement2Capabilities() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + + try { + + String capabilityTypeName1 = CAPABILITY_1; + String capabilityTypeName2 = CAPABILITY_2; + String reqName1 = "host1"; + String reqName2 = "host2"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef1 = capabilityTypeOperationTest + .createCapability(capabilityTypeName1); + CapabilityTypeDefinition createCapabilityDef2 = capabilityTypeOperationTest + .createCapability(capabilityTypeName2); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + // rollbackAndPrint(); + // OKKKKKKK + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + // create compute component + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, + "1.0", rootResource.getName(), true, true); + + // rollbackAndPrint(); + // OKKKKKKKKKK + + // Add capabilities to Compute Resource + CapabilityDefinition capabilty1 = addCapabilityToResource(capabilityTypeName1, reqName1, computeComponent); + CapabilityDefinition capabilty2 = addCapabilityToResource(capabilityTypeName2, reqName2, computeComponent); + + // rollbackAndPrint(); + + // create requirement definition + + Either addRequirementToResource1 = addRequirementToResource( + capabilityTypeName1, reqName1, reqNodeName, reqRelationship, softwareComponent); + + Either addRequirementToResource2 = addRequirementToResource( + capabilityTypeName2, reqName2, reqNodeName, reqRelationship, softwareComponent); + + // create my resource derived from software component + String MY_RESOURCE = "my-resource"; + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, MY_RESOURCE, + myResourceVersion, softwareComponent.getName(), true, true); + + String serviceName = "myservice.1.0"; + String requirementId1 = addRequirementToResource1.left().value().getUniqueId(); + String requirementId2 = addRequirementToResource2.left().value().getUniqueId(); + List resInstances = buildServiceAndConnectBetweenResourceInstances(serviceName, resource, + computeComponent, reqName1, false, capabilty1.getUniqueId(), requirementId1); + + RequirementAndRelationshipPair relationPair = new RequirementAndRelationshipPair(); + relationPair.setRequirement(reqName2); + relationPair.setCapabilityUid(capabilty2.getUniqueId()); + relationPair.setRequirementUid(requirementId2); + relationPair.setCapabilityOwnerId(resInstances.get(1).getUniqueId()); + relationPair.setRequirementOwnerId(resInstances.get(0).getUniqueId()); + Either connectResourcesInService1 = resourceInstanceOperation + .connectResourcesInService(serviceName, NodeTypeEnum.Service, resInstances.get(0).getUniqueId(), + resInstances.get(1).getUniqueId(), relationPair); + assertTrue("check associate resource instances succeed " + reqName2, connectResourcesInService1.isLeft()); + + // rollbackAndPrint(); + + PrintGraph printGraph = new PrintGraph(); + String webGraph = printGraph.buildGraphForWebgraphWiz(titanDao.getGraph().left().value()); + log.debug(webGraph); + + RequirementCapabilityRelDef reqCapDef = new RequirementCapabilityRelDef(); + reqCapDef.setFromNode(resInstances.get(0).getUniqueId()); + reqCapDef.setToNode(resInstances.get(1).getUniqueId()); + + relationPair.setRequirement(reqName1); + relationPair.setCapabilityUid(capabilty1.getUniqueId()); + relationPair.setRequirementUid(requirementId1); + RelationshipImpl relationship = new RelationshipImpl(); + relationship.setType(reqName1); + relationPair.setRelationships(relationship); + + List list = new ArrayList<>(); + list.add(relationPair); + reqCapDef.setRelationships(list); + + disconnectResourcesInService(serviceName, reqCapDef); + + reqCapDef.getRelationships().clear(); + + RequirementAndRelationshipPair relationPair1 = new RequirementAndRelationshipPair(); + relationPair1.setRequirement(reqName2); + relationPair1.setCapabilityUid(capabilty2.getUniqueId()); + relationPair1.setRequirementUid(requirementId2); + relationPair1.setCapabilityOwnerId(resInstances.get(1).getUniqueId()); + relationPair1.setRequirementOwnerId(resInstances.get(0).getUniqueId()); + relationship.setType(reqName2); + relationPair1.setRelationships(relationship); + reqCapDef.getRelationships().add(relationPair1); + + disconnectResourcesInService(serviceName, reqCapDef); + + RequirementCapabilityRelDef relation = new RequirementCapabilityRelDef(); + String fromResUid = resInstances.get(0).getUniqueId(); + String toResUid = resInstances.get(1).getUniqueId(); + relation.setFromNode(fromResUid); + relation.setToNode(toResUid); + List relationships = new ArrayList(); + RequirementAndRelationshipPair immutablePair1 = new RequirementAndRelationshipPair(reqName1, null); + RequirementAndRelationshipPair immutablePair2 = new RequirementAndRelationshipPair(reqName2, null); + immutablePair1.setCapabilityUid(capabilty1.getUniqueId()); + immutablePair1.setRequirementUid(addRequirementToResource1.left().value().getUniqueId()); + immutablePair1.setRequirementOwnerId(resInstances.get(0).getUniqueId()); + immutablePair1.setCapabilityOwnerId(resInstances.get(1).getUniqueId()); + + immutablePair2.setCapabilityUid(capabilty2.getUniqueId()); + immutablePair2.setRequirementUid(addRequirementToResource2.left().value().getUniqueId()); + immutablePair2.setRequirementOwnerId(resInstances.get(0).getUniqueId()); + immutablePair2.setCapabilityOwnerId(resInstances.get(1).getUniqueId()); + + relationships.add(immutablePair1); + relationships.add(immutablePair2); + relation.setRelationships(relationships); + + Either associateResourceInstances = resourceInstanceOperation + .associateResourceInstances(serviceName, NodeTypeEnum.Service, relation, true); + assertTrue("check return code after associating 2 requirements in one request", + associateResourceInstances.isLeft()); + RequirementCapabilityRelDef capabilityRelDef = associateResourceInstances.left().value(); + String fromNode = capabilityRelDef.getFromNode(); + assertEquals("check from node", resInstances.get(0).getUniqueId(), fromNode); + String toNode = capabilityRelDef.getToNode(); + assertEquals("check to node", resInstances.get(1).getUniqueId(), toNode); + List relationships2 = capabilityRelDef.getRelationships(); + assertEquals("check number of relations", 2, relationships2.size()); + + for (RequirementAndRelationshipPair pair : relationships2) { + String key = pair.getRequirement(); + RelationshipImpl relationshipImpl = pair.getRelationship(); + if (key.equals(reqName1)) { + String type = relationshipImpl.getType(); + assertEquals("Check relationship type name", reqRelationship, type); + } else if (key.equals(reqName2)) { + String type = relationshipImpl.getType(); + assertEquals("Check relationship type name", reqRelationship, type); + } else { + assertTrue("requirement " + key + " was not found in the original request", false); + } + } + + verifyGetAllResourceInstanceFromService(reqName1, reqName2, serviceName, fromResUid, toResUid); + + List resourcesPathList = new ArrayList(); + TitanOperationStatus findResourcesPathRecursively = resourceOperation + .findResourcesPathRecursively(resource.getUniqueId(), resourcesPathList); + assertEquals("check returned status", TitanOperationStatus.OK, findResourcesPathRecursively); + assertEquals("check list size", 3, resourcesPathList.size()); + + TitanOperationStatus validateTheTargetResourceInstance = resourceInstanceOperation + .validateTheTargetResourceInstance(MY_RESOURCE, resource.getUniqueId()); + assertEquals("check resource name in the path", TitanOperationStatus.OK, validateTheTargetResourceInstance); + validateTheTargetResourceInstance = resourceInstanceOperation + .validateTheTargetResourceInstance(softwareCompName, resource.getUniqueId()); + assertEquals("check resource name in the path", TitanOperationStatus.OK, validateTheTargetResourceInstance); + + validateTheTargetResourceInstance = resourceInstanceOperation + .validateTheTargetResourceInstance(softwareCompName + "STAM", resource.getUniqueId()); + assertEquals("check resource name not in the path", TitanOperationStatus.MATCH_NOT_FOUND, + validateTheTargetResourceInstance); + + Either deleteResourceInstance = resourceInstanceOperation + .deleteComponentInstance(NodeTypeEnum.Service, serviceName, toResUid, true); + assertTrue("check resource instance was deleted.", deleteResourceInstance.isLeft()); + + } finally { + rollbackAndPrint(false); + compareGraphSize(numberOfVertices); + } + + } + + private void verifyGetAllResourceInstanceFromService(String reqName1, String reqName2, String serviceName, + String fromResUid, String toResUid) { + + Either, List>, StorageOperationStatus> allResourceInstances = resourceInstanceOperation + .getAllComponentInstances(serviceName, NodeTypeEnum.Service, NodeTypeEnum.Resource, true); + // assertTrue("check return code after get all resource instances", + // associateResourceInstances.isLeft()); + ImmutablePair, List> immutablePair = allResourceInstances + .left().value(); + List nodes = immutablePair.getKey(); + List edges = immutablePair.getValue(); + assertEquals("check 2 nodes returned", 2, nodes.size()); + assertEquals("check one relation returned", 1, edges.size()); + RequirementCapabilityRelDef requirementCapabilityRelDef = edges.get(0); + assertEquals("check from node", requirementCapabilityRelDef.getFromNode(), fromResUid); + requirementCapabilityRelDef.getToNode(); + assertEquals("check to node", requirementCapabilityRelDef.getToNode(), toResUid); + int size = requirementCapabilityRelDef.getRelationships().size(); + assertEquals("check number of relations", 2, size); + String req1 = requirementCapabilityRelDef.getRelationships().get(0).getRequirement(); + String req2 = requirementCapabilityRelDef.getRelationships().get(1).getRequirement(); + + List requirements = new ArrayList(); + requirements.add(req1); + requirements.add(req2); + + assertTrue("check requirement returned " + reqName1, requirements.contains(reqName1)); + assertTrue("check requirement returned " + reqName2, requirements.contains(reqName2)); + + String nodesStr = prettyGson.toJson(nodes); + String edgesStr = prettyGson.toJson(edges); + + log.debug(nodesStr); + log.debug(edgesStr); + } + + private Either addRequirementToResource(String capabilityTypeName1, + String reqName1, String reqNodeName, String reqRelationship, Resource softwareComponent) { + RequirementDefinition reqDefinition1 = new RequirementDefinition(); + reqDefinition1.setNode(reqNodeName); + reqDefinition1.setRelationship(reqRelationship); + reqDefinition1.setCapability(capabilityTypeName1); + // add requirement to software component + Either addRequirementToResource = requirementOperation + .addRequirementToResource(reqName1, reqDefinition1, softwareComponent.getUniqueId(), true); + assertEquals("check requirement was added", true, addRequirementToResource.isLeft()); + return addRequirementToResource; + } + + private CapabilityDefinition addCapabilityToResource(String capabilityTypeName1, String reqName1, + Resource computeComponent) { + CapabilityDefinition capabilityDefinition1 = new CapabilityDefinition(); + capabilityDefinition1.setDescription("my capability"); + capabilityDefinition1.setType(capabilityTypeName1); + List validSourceTypes = new ArrayList(); + validSourceTypes.add("tosca.nodes.SC"); + capabilityDefinition1.setValidSourceTypes(validSourceTypes); + Either addCapability = capabilityOperation + .addCapability(computeComponent.getUniqueId(), reqName1, capabilityDefinition1, true); + assertTrue("check capability created ", addCapability.isLeft()); + return addCapability.left().value(); + } + + @Test + public void testConnectResourceInstancesCapabilityNameDiffFromReqName() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + + try { + + String capabilityTypeName = CAPABILITY_2; + String reqName = "host"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + String DIFFERENT_CAPABILITY = "hostDiffernet"; + + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef = capabilityTypeOperationTest + .createCapability(capabilityTypeName); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + // create compute component + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, + "1.0", rootResource.getName(), true, true); + + CapabilityDefinition capabilty = addCapabilityToResource(capabilityTypeName, DIFFERENT_CAPABILITY, + computeComponent); + + // create requirement definition + + Either addRequirementToResource = addRequirementToResource( + capabilityTypeName, reqName, reqNodeName, reqRelationship, softwareComponent); + + String parentReqUniqId = addRequirementToResource.left().value().getUniqueId(); + + // create my resource derived from software component + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", + myResourceVersion, softwareComponent.getName(), true, true); + + String serviceName = "myservice.1.0"; + List resInstances = buildServiceAndConnectBetweenResourceInstances(serviceName, resource, + computeComponent, "host", false, capabilty.getUniqueId(), parentReqUniqId); + + PrintGraph printGraph = new PrintGraph(); + String webGraph = printGraph.buildGraphForWebgraphWiz(titanDao.getGraph().left().value()); + // log.debug(webGraph); + + } finally { + rollbackAndPrint(); + + compareGraphSize(numberOfVertices); + } + + } + + @Test + public void testConnectResourceInstancesInvalidCapability() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + + try { + + String capabilityTypeName = CAPABILITY_2; + String reqName = "host"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + String capabilityTypeNameOther = CAPABILITY_2 + "othertype"; + + String DIFFERENT_CAPABILITY = "hostDiffernet"; + + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef = capabilityTypeOperationTest + .createCapability(capabilityTypeName); + + CapabilityTypeDefinition createCapabilityDef2 = capabilityTypeOperationTest + .createCapability(capabilityTypeNameOther); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + // create compute component + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, + "1.0", rootResource.getName(), true, true); + + addCapabilityToResource(capabilityTypeName, DIFFERENT_CAPABILITY, computeComponent); + + // create requirement definition + + Either addRequirementToResource = addRequirementToResource( + capabilityTypeNameOther, reqName, reqNodeName, reqRelationship, softwareComponent); + + String parentReqUniqId = addRequirementToResource.left().value().getUniqueId(); + + // create my resource derived from software component + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", + myResourceVersion, softwareComponent.getName(), true, true); + + String serviceName = "myservice.1.0"; + List resInstances = buildServiceAndConnectBetweenResourceInstancesWithError(serviceName, + resource, computeComponent, "host", false, TitanOperationStatus.ILLEGAL_ARGUMENT); + + PrintGraph printGraph = new PrintGraph(); + String webGraph = printGraph.buildGraphForWebgraphWiz(titanDao.getGraph().left().value()); + log.debug(webGraph); + + } finally { + rollbackAndPrint(); + + compareGraphSize(numberOfVertices); + } + + } + + private void compareGraphSize(int numberOfVertices, Set toRemoveFromSet) { + PrintGraph printGraph2 = new PrintGraph(); + int numberOfVerticesCurr = printGraph2.getNumberOfVertices(titanDao.getGraph().left().value()); + + Set set = printGraph2.getVerticesSet(titanDao.getGraph().left().value()); + if (toRemoveFromSet != null) { + set.removeAll(toRemoveFromSet); + } + + assertEquals("check all data deleted from graph " + set, numberOfVertices, numberOfVerticesCurr); + } + + private void compareGraphSize(int numberOfVertices) { + PrintGraph printGraph2 = new PrintGraph(); + int numberOfVerticesCurr = printGraph2.getNumberOfVertices(titanDao.getGraph().left().value()); + + assertEquals( + "check all data deleted from graph " + printGraph2.getVerticesSet(titanDao.getGraph().left().value()), + numberOfVertices, numberOfVerticesCurr); + } + + @Test + public void testConnectResourceInstancesRequirementNotFound() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + try { + + String capabilityTypeName = CAPABILITY_2; + String reqName = "host"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + String DIFFERENT_CAPABILITY = "hostDiffernet"; + + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef = capabilityTypeOperationTest + .createCapability(capabilityTypeName); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + // create compute component + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, + "1.0", rootResource.getName(), true, true); + + addCapabilityToResource(capabilityTypeName, reqName, computeComponent); + + // create requirement definition + + RequirementDefinition reqDefinition = new RequirementDefinition(); + reqDefinition.setNode(reqNodeName); + reqDefinition.setRelationship(reqRelationship); + reqDefinition.setCapability(capabilityTypeName); + // add requirement to software component + Either addRequirementToResource = requirementOperation + .addRequirementToResource(reqName + "ssssssss", reqDefinition, softwareComponent.getUniqueId(), + true); + assertEquals("check requirement was added", true, addRequirementToResource.isLeft()); + + String parentReqUniqId = addRequirementToResource.left().value().getUniqueId(); + + // create my resource derived from software component + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", + myResourceVersion, softwareComponent.getName(), true, true); + + String serviceName = "myservice.1.0"; + List resInstances = buildServiceAndConnectBetweenResourceInstancesWithError(serviceName, + resource, computeComponent, "host", false, TitanOperationStatus.ILLEGAL_ARGUMENT); + + PrintGraph printGraph = new PrintGraph(); + String webGraph = printGraph.buildGraphForWebgraphWiz(titanDao.getGraph().left().value()); + log.debug(webGraph); + + } finally { + titanDao.rollback(); + + compareGraphSize(numberOfVertices); + } + + } + + private void disconnectResourcesInService(String serviceName, RequirementCapabilityRelDef reqCapDef) { + + Either, TitanOperationStatus> disconnectResourcesInService = resourceInstanceOperation + .disconnectResourcesInService(serviceName, NodeTypeEnum.Service, reqCapDef); + assertTrue("check relatioship instance was deleted", disconnectResourcesInService.isLeft()); + + disconnectResourcesInService = resourceInstanceOperation.disconnectResourcesInService(serviceName, + NodeTypeEnum.Service, reqCapDef); + assertTrue("check relatioship instance already was deleted", disconnectResourcesInService.isRight()); + assertEquals("check relatioship instance already was deleted. status NOT_FOUND", TitanOperationStatus.NOT_FOUND, + disconnectResourcesInService.right().value()); + } + + private List buildServiceAndConnectBetweenResourceInstancesWithError(String serviceName, + Resource resource, Resource computeComponent, String requirement, boolean ignoreCreatingService, + TitanOperationStatus titanOperationStatus) { + + String serviceId = "myservice.1.0"; + + if (false == ignoreCreatingService) { + ServiceMetadataData createService = createService(serviceId); + } + ComponentInstance myresourceInstance = buildResourceInstance(resource.getUniqueId(), "1", resource.getName()); + + ComponentInstance computeInstance = buildResourceInstance(computeComponent.getUniqueId(), "2", + computeComponent.getName()); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", myinstanceRes.isLeft()); + ComponentInstance value1 = myinstanceRes.left().value(); + Either computeInstTes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "2", true, computeInstance, + NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", computeInstTes.isLeft()); + ComponentInstance value2 = computeInstTes.left().value(); + + RequirementAndRelationshipPair relationPair = new RequirementAndRelationshipPair(); + relationPair.setRequirement(requirement); + + Either connectResourcesInService = resourceInstanceOperation + .connectResourcesInService(serviceId, NodeTypeEnum.Service, value1.getUniqueId(), value2.getUniqueId(), + relationPair); + + assertTrue("check relation was not created", connectResourcesInService.isRight()); + assertEquals("check error code after connect resource instances failed", titanOperationStatus, + connectResourcesInService.right().value()); + + List resInstances = new ArrayList(); + resInstances.add(value1); + + return resInstances; + + } + + private List buildServiceAndConnectBetweenResourceInstances(String serviceName, + Resource resource, Resource computeComponent, String requirement, boolean ignoreCreatingService, + String capabilityId, String requirementId) { + + String serviceId = "myservice.1.0"; + + if (false == ignoreCreatingService) { + ServiceMetadataData createService = createService(serviceId); + } + ComponentInstance myresourceInstance = buildResourceInstance(resource.getUniqueId(), "1", resource.getName()); + + ComponentInstance computeInstance = buildResourceInstance(computeComponent.getUniqueId(), "2", + computeComponent.getName()); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", myinstanceRes.isLeft()); + ComponentInstance value1 = myinstanceRes.left().value(); + Either computeInstTes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "2", true, computeInstance, + NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", computeInstTes.isLeft()); + ComponentInstance value2 = computeInstTes.left().value(); + RequirementAndRelationshipPair relationPair = new RequirementAndRelationshipPair(); + relationPair.setRequirement(requirement); + + relationPair.setCapabilityUid(capabilityId); + relationPair.setRequirementUid(requirementId); + relationPair.setRequirementOwnerId(value1.getUniqueId()); + relationPair.setCapabilityOwnerId(value2.getUniqueId()); + + Either connectResourcesInService = resourceInstanceOperation + .connectResourcesInService(serviceId, NodeTypeEnum.Service, value1.getUniqueId(), value2.getUniqueId(), + relationPair); + + assertTrue("check relation created", connectResourcesInService.isLeft()); + + List resInstances = new ArrayList(); + resInstances.add(value1); + resInstances.add(value2); + + return resInstances; + + } + + @Test + public void getAllResourceInstancesThree() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + try { + + Set vertexSetBeforeMethod = printGraph1.getVerticesSet(titanDao.getGraph().left().value()); + + String capabilityTypeName = CAPABILITY_2; + String reqName = "host"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef = capabilityTypeOperationTest + .createCapability(capabilityTypeName); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + // create compute component + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, + "1.0", rootResource.getName(), true, true); + + // rollbackAndPrint(); + + // Add capabilities to Compute Resource + CapabilityDefinition capability = addCapabilityToResource(capabilityTypeName, "host", computeComponent); + + // create requirement definition + + Either addRequirementToResource = addRequirementToResource( + capabilityTypeName, reqName, reqNodeName, reqRelationship, softwareComponent); + + String parentReqUniqId = addRequirementToResource.left().value().getUniqueId(); + + // create my resource derived from software component + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", + myResourceVersion, softwareComponent.getName(), true, true); + + String serviceId = "myservice.1.0"; + + ServiceMetadataData createService = createService(serviceId); + + Either, List>, StorageOperationStatus> allResourceInstances = resourceInstanceOperation + .getAllComponentInstances(serviceId, NodeTypeEnum.Service, NodeTypeEnum.Resource, true); + assertTrue("check NOT_FOUND is returned", allResourceInstances.isRight()); + assertEquals("check NOT_FOUND is returned", allResourceInstances.right().value(), + StorageOperationStatus.NOT_FOUND); + + ComponentInstance myresourceInstance = buildResourceInstance(resource.getUniqueId(), "1", "my-resource"); + myresourceInstance.setName("my-resource"); + + ComponentInstance computeInstance1 = buildResourceInstance(computeComponent.getUniqueId(), "2", + "tosca.nodes.Compute2"); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", myinstanceRes.isLeft()); + ComponentInstance value1 = myinstanceRes.left().value(); + + allResourceInstances = resourceInstanceOperation.getAllComponentInstances(serviceId, NodeTypeEnum.Service, + NodeTypeEnum.Resource, true); + assertTrue("check resource instances found", allResourceInstances.isLeft()); + ImmutablePair, List> immutablePair = allResourceInstances + .left().value(); + List nodes = immutablePair.getKey(); + List edges = immutablePair.getValue(); + + assertEquals("check resource instances size", 1, nodes.size()); + assertEquals("check resource instances size", 0, edges.size()); + + Either computeInstTes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "2", true, + computeInstance1, NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", computeInstTes.isLeft()); + ComponentInstance value2 = computeInstTes.left().value(); + + allResourceInstances = resourceInstanceOperation.getAllComponentInstances(serviceId, NodeTypeEnum.Service, + NodeTypeEnum.Resource, true); + assertTrue("check resource instances found", allResourceInstances.isLeft()); + immutablePair = allResourceInstances.left().value(); + nodes = immutablePair.getKey(); + edges = immutablePair.getValue(); + + assertEquals("check resource instances size", 2, nodes.size()); + assertEquals("check resource instances size", 0, edges.size()); + + String requirement = "host"; + RequirementAndRelationshipPair relationPair = new RequirementAndRelationshipPair(); + relationPair.setRequirement(requirement); + relationPair.setCapabilityUid(capability.getUniqueId()); + relationPair.setRequirementUid(addRequirementToResource.left().value().getUniqueId()); + relationPair.setRequirementOwnerId(value1.getUniqueId()); + relationPair.setCapabilityOwnerId(value2.getUniqueId()); + + Either connectResourcesInService = resourceInstanceOperation + .connectResourcesInService(serviceId, NodeTypeEnum.Service, value1.getUniqueId(), + value2.getUniqueId(), relationPair); + + assertTrue("check relation created", connectResourcesInService.isLeft()); + + allResourceInstances = resourceInstanceOperation.getAllComponentInstances(serviceId, NodeTypeEnum.Service, + NodeTypeEnum.Resource, true); + assertTrue("check resource instances found", allResourceInstances.isLeft()); + immutablePair = allResourceInstances.left().value(); + nodes = immutablePair.getKey(); + edges = immutablePair.getValue(); + + assertEquals("check resource instances size", 2, nodes.size()); + assertEquals("check resource instances size", 1, edges.size()); + + List resInstances2 = new ArrayList(); + resInstances2.add(value1); + resInstances2.add(value2); + + ComponentInstance myresourceInstance2 = buildResourceInstance(resource.getUniqueId(), "1", "myresource2"); + + Either newResource = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "3", true, + myresourceInstance2, NodeTypeEnum.Resource, false); + + assertTrue("added resource instance successfully", newResource.isLeft()); + + relationPair.setRequirement(requirement); + relationPair.setRequirementOwnerId(newResource.left().value().getUniqueId()); + + Either connectResourcesInService2 = resourceInstanceOperation + .connectResourcesInService(serviceId, NodeTypeEnum.Service, + newResource.left().value().getUniqueId(), value2.getUniqueId(), relationPair); + assertTrue("check resource instance was added to service", connectResourcesInService2.isLeft()); + + allResourceInstances = resourceInstanceOperation.getAllComponentInstances(serviceId, NodeTypeEnum.Service, + NodeTypeEnum.Resource, true); + assertTrue("check resource instances found", allResourceInstances.isLeft()); + immutablePair = allResourceInstances.left().value(); + nodes = immutablePair.getKey(); + edges = immutablePair.getValue(); + + assertEquals("check resource instances size", 3, nodes.size()); + assertEquals("check resource instances size", 2, edges.size()); + + Either, TitanOperationStatus> deleteAllResourceInstancesOfService = resourceInstanceOperation + .deleteAllComponentInstancesInternal(serviceId, NodeTypeEnum.Service); + assertTrue("check resource instances was deleted.", deleteAllResourceInstancesOfService.isLeft()); + assertEquals("check number of deleted resource instances.", 3, + deleteAllResourceInstancesOfService.left().value().size()); + + Either, TitanOperationStatus> allRelatinshipInst = titanDao + .getAll(NodeTypeEnum.RelationshipInst, RelationshipInstData.class); + assertTrue("allRelatinshipInst is empty", allRelatinshipInst.isRight()); + assertEquals("allRelatinshipInst result is NOT_FOUND", TitanOperationStatus.NOT_FOUND, + allRelatinshipInst.right().value()); + + Either deleteComputeResource = resourceOperation + .deleteResource(computeComponent.getUniqueId(), true); + assertTrue("delete compute resource succeed", deleteComputeResource.isLeft()); + + Either deleteSCResource = resourceOperation + .deleteResource(softwareComponent.getUniqueId(), true); + assertTrue("delete software component resource succeed", deleteSCResource.isLeft()); + + Either deleteMyResource = resourceOperation + .deleteResource(resource.getUniqueId(), true); + assertTrue("delete my resource succeed", deleteMyResource.isLeft()); + + Either rootResourceDeleted = resourceOperation + .deleteResource(rootResource.getUniqueId(), true); + assertTrue("delete root resource succeed", rootResourceDeleted.isLeft()); + + Set vertexSetAfterDelete = printGraph1.getVerticesSet(titanDao.getGraph().left().value()); + + vertexSetAfterDelete.removeAll(vertexSetBeforeMethod); + + log.debug("vertexSetAfterDelete={}", vertexSetAfterDelete); + log.debug("vertexSetAfterDelete size={}", vertexSetAfterDelete.size()); + + // int numberOfVerticesAfterOperation = + // printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + // System.out.println(numberOfVerticesAfterOperation); + // 6 - service, 2 tags, capability + 2 parameters + // compareGraphSize(numberOfVertices + 6, vertexSetBeforeMethod); + + } finally { + rollbackAndPrint(false); + compareGraphSize(numberOfVertices); + // printGraph1.printGraphVertices(titanDao.getGraph().left().value()); + } + + } + + public void testCreateRootResource() { + + String name = "tosca.nodes.Root"; + + String state = LifecycleStateEnum.CERTIFIED.name(); + + ResourceMetadataData resourceData1 = new ResourceMetadataData(); + resourceData1.getMetadataDataDefinition().setUniqueId(UniqueIdBuilder.buildResourceUniqueId()); + resourceData1.getMetadataDataDefinition().setName(name); + resourceData1.getMetadataDataDefinition().setState(state); + resourceData1.getMetadataDataDefinition().setHighestVersion(true); + resourceData1.getMetadataDataDefinition().setContactId("contactId"); + Either createNode1 = titanDao.createNode(resourceData1, + ResourceMetadataData.class); + + log.debug("{}", createNode1); + + titanDao.commit(); + } + + public void testMultiResourceCertified() { + boolean create = true; + String name = "myresource7"; + if (create) { + + String state = LifecycleStateEnum.CERTIFIED.name(); + boolean isHighestVersion = true; + + ResourceMetadataData resourceData1 = new ResourceMetadataData(); + resourceData1.getMetadataDataDefinition().setUniqueId(name + "." + "1.0"); + resourceData1.getMetadataDataDefinition().setName(name); + resourceData1.getMetadataDataDefinition().setState(state); + resourceData1.getMetadataDataDefinition().setHighestVersion(true); + resourceData1.getMetadataDataDefinition().setContactId("contactId"); + Either createNode1 = titanDao.createNode(resourceData1, + ResourceMetadataData.class); + + log.debug("{}", createNode1); + + titanDao.commit(); + + // resourceData1.setHighestVersion(false); + resourceData1.getMetadataDataDefinition().setContactId("222contactId222"); + Either updateNode = titanDao.updateNode(resourceData1, + ResourceMetadataData.class); + + titanDao.commit(); + + // TitanGraph titanGraph = titanDao.getGraph().left().value(); + // Iterable> vertices = + // titanGraph.indexQuery("highestVersion", + // "v.highestVersion:true").vertices(); + // for (Result vertex : vertices) { + // Vertex element = vertex.getElement(); + // System.out.println( ElementHelper.getProperties(element)); + // } + + } + + Either, TitanOperationStatus> byCriteria = searchForResource(name); + + log.debug("{}", byCriteria.left().value().size()); + + byCriteria = searchForResource(name); + + log.debug("{}", byCriteria.left().value().size()); + + } + + private Either, TitanOperationStatus> searchForResource(String name) { + Map propertiesToMatch = new HashMap(); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + // propertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), + // true); + propertiesToMatch.put(GraphPropertiesDictionary.NAME.getProperty(), name); + propertiesToMatch.put(GraphPropertiesDictionary.CONTACT_ID.getProperty(), "contactId"); + // propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), + // true); + Either, TitanOperationStatus> byCriteria = titanDao + .getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + return byCriteria; + } + + @Test + public void testCreateResourceInstanceTwice() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + try { + + String capabilityTypeName = CAPABILITY_2; + String reqName = "host"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + ComponentInstance myresourceInstance = buildResourceInstance(softwareComponent.getUniqueId(), "1", + softwareCompName); + + String serviceName = "myservice.1.0"; + ServiceMetadataData createService = createService(serviceName); + Either myinstanceRes1 = resourceInstanceOperation + .createComponentInstance(serviceName, NodeTypeEnum.Service, "1", myresourceInstance, + NodeTypeEnum.Resource, true); + assertTrue("check resource instance was created", myinstanceRes1.isLeft()); + + Either myinstanceRes2 = resourceInstanceOperation + .createComponentInstance(serviceName, NodeTypeEnum.Service, "1", myresourceInstance, + NodeTypeEnum.Resource, true); + assertTrue("check resource instance was not created", myinstanceRes2.isRight()); + assertEquals("check error code", StorageOperationStatus.SCHEMA_VIOLATION, myinstanceRes2.right().value()); + + Either deleteResourceInstance = resourceInstanceOperation + .deleteComponentInstance(NodeTypeEnum.Service, serviceName, + myinstanceRes1.left().value().getUniqueId(), true); + assertTrue("check resource instance was deleted", deleteResourceInstance.isLeft()); + + deleteResourceInstance = resourceInstanceOperation.deleteComponentInstance(NodeTypeEnum.Service, + serviceName, myinstanceRes1.left().value().getUniqueId(), true); + assertTrue("check resource instance was not deleted", deleteResourceInstance.isRight()); + assertEquals("check resource instance was not deleted", StorageOperationStatus.NOT_FOUND, + deleteResourceInstance.right().value()); + + } finally { + rollbackAndPrint(false); + compareGraphSize(numberOfVertices); + } + + } + + @Test + public void testConnectResourceInstancesTwice() { + + PrintGraph printGraph1 = new PrintGraph(); + int numberOfVertices = printGraph1.getNumberOfVertices(titanDao.getGraph().left().value()); + + try { + + String capabilityTypeName1 = CAPABILITY_1; + String capabilityTypeName2 = CAPABILITY_2; + String reqName1 = "host1"; + String reqName2 = "host2"; + String reqNodeName = "tosca.nodes.Compute2" + TEST_CLASS_NUMBER; + String rootName = "Root2" + TEST_CLASS_NUMBER; + String softwareCompName = "tosca.nodes.SoftwareComponent2" + TEST_CLASS_NUMBER; + String computeNodeName = reqNodeName; + String myResourceVersion = "4.0" + TEST_CLASS_NUMBER; + String reqRelationship = "myrelationship"; + + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef1 = capabilityTypeOperationTest + .createCapability(capabilityTypeName1); + CapabilityTypeDefinition createCapabilityDef2 = capabilityTypeOperationTest + .createCapability(capabilityTypeName2); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + // create root resource + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, + true, true); + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + + // create software component + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + // create compute component + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, + "1.0", rootResource.getName(), true, true); + + // Add capabilities to Compute Resource + CapabilityDefinition capabilty1 = addCapabilityToResource(capabilityTypeName1, reqName1, computeComponent); + CapabilityDefinition capabilty2 = addCapabilityToResource(capabilityTypeName2, reqName2, computeComponent); + + // rollbackAndPrint(); + + // create requirement definition + + Either addRequirementToResource = addRequirementToResource( + capabilityTypeName1, reqName1, reqNodeName, reqRelationship, softwareComponent); + + String parentReqUniqId = addRequirementToResource.left().value().getUniqueId(); + + // create my resource derived from software component + Resource resource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, "my-resource", + myResourceVersion, softwareComponent.getName(), true, true); + + String serviceId = "myservice.1.0"; + + ServiceMetadataData createService = createService(serviceId); + ComponentInstance myresourceInstance = buildResourceInstance(resource.getUniqueId(), "1", "my-resource"); + + ComponentInstance computeInstance = buildResourceInstance(computeComponent.getUniqueId(), "2", + computeNodeName); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", myinstanceRes.isLeft()); + ComponentInstance value1 = myinstanceRes.left().value(); + Either computeInstTes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "2", true, + computeInstance, NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", computeInstTes.isLeft()); + ComponentInstance value2 = computeInstTes.left().value(); + + RequirementCapabilityRelDef relation = new RequirementCapabilityRelDef(); + String fromResUid = value1.getUniqueId(); + String toResUid = value2.getUniqueId(); + relation.setFromNode(fromResUid); + relation.setToNode(toResUid); + List relationships = new ArrayList(); + RequirementAndRelationshipPair immutablePair1 = new RequirementAndRelationshipPair(reqName1, null); + immutablePair1.setCapabilityUid(capabilty1.getUniqueId()); + immutablePair1.setRequirementUid(parentReqUniqId); + immutablePair1.setRequirementOwnerId(fromResUid); + immutablePair1.setCapabilityOwnerId(toResUid); + relationships.add(immutablePair1); + + relation.setRelationships(relationships); + + Either connectResourcesInService = resourceInstanceOperation + .associateResourceInstances(serviceId, NodeTypeEnum.Service, relation, true); + assertTrue("check association succeed", connectResourcesInService.isLeft()); + + relationships.clear(); + RequirementAndRelationshipPair immutablePair2 = new RequirementAndRelationshipPair(reqName2, null); + immutablePair2.setCapabilityUid(capabilty2.getUniqueId()); + immutablePair2.setRequirementUid(parentReqUniqId); + relationships.add(immutablePair2); + + RequirementCapabilityRelDef firstRelation = connectResourcesInService.left().value(); + connectResourcesInService = resourceInstanceOperation.associateResourceInstances(serviceId, + NodeTypeEnum.Service, relation, true); + assertTrue("check association succeed", connectResourcesInService.isRight()); + assertEquals("check association failed", StorageOperationStatus.MATCH_NOT_FOUND, + connectResourcesInService.right().value()); + + Either disconnectResourcesInService = resourceInstanceOperation + .dissociateResourceInstances(serviceId, NodeTypeEnum.Service, firstRelation, true); + + assertTrue("check dissociation succeed", disconnectResourcesInService.isLeft()); + + disconnectResourcesInService = resourceInstanceOperation.dissociateResourceInstances(serviceId, + NodeTypeEnum.Service, relation, true); + + assertTrue("check dissociation failed", disconnectResourcesInService.isRight()); + assertEquals("check association failed", StorageOperationStatus.NOT_FOUND, + disconnectResourcesInService.right().value()); + } finally { + rollbackAndPrint(); + compareGraphSize(numberOfVertices); + } + + } + + private Resource createComputeWithCapability(String capabilityTypeName, String computeNodeName, + ResourceOperationTest resourceOperationTest, Resource rootResource) { + // create compute component + // String id = UniqueIdBuilder.buildResourceUniqueId(computeNodeName, + // "1.0"); + // if (resourceOperation.getResource(id).isLeft()){ + // resourceOperation.deleteResource(id); + // } + Either, StorageOperationStatus> oldResource = resourceOperation + .getResourceByNameAndVersion(computeNodeName, "1.0", false); + if (oldResource.isLeft()) { + for (Resource old : oldResource.left().value()) { + if (old.getResourceType().equals(ResourceTypeEnum.VFC)) { + resourceOperation.deleteResource(old.getUniqueId()); + } + } + + } + + Resource computeComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, computeNodeName, "1.0", + rootResource.getName(), true, true); + + // rollbackAndPrint(); + + // Add capabilities to Compute Resource + addCapabilityToResource(capabilityTypeName, "host", computeComponent); + return resourceOperation.getResource(computeComponent.getUniqueId()).left().value(); + } + + private Resource createSoftwareComponentWithReq(String softwareCompName, + ResourceOperationTest resourceOperationTest, Resource rootResource, String capabilityTypeName, + String reqName, String reqRelationship, String reqNodeName) { + Either updateNode; + ResourceMetadataData resourceData = new ResourceMetadataData(); + // create software component + // String id = UniqueIdBuilder.buildResourceUniqueId(softwareCompName, + // "1.0"); + // if (resourceOperation.getResource(id).isLeft()){ + // resourceOperation.deleteResource(id); + // } + Either, StorageOperationStatus> oldResource = resourceOperation + .getResourceByNameAndVersion(softwareCompName, "1.0", false); + if (oldResource.isLeft()) { + if (oldResource.isLeft()) { + for (Resource old : oldResource.left().value()) { + if (old.getResourceType().equals(ResourceTypeEnum.VFC)) { + resourceOperation.deleteResource(old.getUniqueId()); + } + } + + } + } + + Resource softwareComponent = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, softwareCompName, + "1.0", rootResource.getName(), true, true); + + resourceData.getMetadataDataDefinition().setUniqueId(softwareComponent.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + updateNode = titanDao.updateNode(resourceData, ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either addRequirementToResource = addRequirementToResource( + capabilityTypeName, reqName, reqNodeName, reqRelationship, softwareComponent); + + String parentReqUniqId = addRequirementToResource.left().value().getUniqueId(); + + return resourceOperation.getResource(softwareComponent.getUniqueId()).left().value(); + } + + private Resource createRootResource(String rootName, ResourceOperationTest resourceOperationTest) { + // create root resource + // String rootId = UniqueIdBuilder.buildResourceUniqueId(rootName, + // "1.0"); + Either, StorageOperationStatus> oldResource = resourceOperation + .getResourceByNameAndVersion(rootName, "1.0", false); + if (oldResource.isLeft()) { + for (Resource old : oldResource.left().value()) { + if (old.getResourceType().equals(ResourceTypeEnum.VFC)) { + resourceOperation.deleteResource(old.getUniqueId()); + } + } + + } + Resource rootResource = resourceOperationTest.createResource(USER_ID, CATEGORY_NAME, rootName, "1.0", null, true, + true); + ResourceMetadataData rootResourceData = new ResourceMetadataData(); + rootResourceData.getMetadataDataDefinition().setUniqueId(rootResource.getUniqueId()); + rootResourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(rootResourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Either fetchRootResource = resourceOperation + .getResource(rootResource.getUniqueId(), true); + + String rootResourceJson = prettyGson.toJson(fetchRootResource.left().value()); + log.debug(rootResourceJson); + return rootResource; + } + + public void addResourceInstancesAndRelation(String serviceId) { + + String rootName = "tosca.nodes.test.root"; + String softwareCompName = "tosca.nodes.test.softwarecomponent"; + String capabilityTypeName = "myCapability"; + String reqName = "host"; + String computeNodeName = "tosca.nodes.test.compute"; + String reqRelationship = "myRelationship"; + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource rootResource = createRootResource(rootName, resourceOperationTest); + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + CapabilityTypeDefinition createCapabilityDef = capabilityTypeOperationTest.createCapability(capabilityTypeName); + + Resource softwareComponentResource = createSoftwareComponentWithReq(softwareCompName, resourceOperationTest, + rootResource, capabilityTypeName, reqName, reqRelationship, computeNodeName); + Resource compute = createComputeWithCapability(capabilityTypeName, computeNodeName, resourceOperationTest, + rootResource); + + // resource1 + ComponentInstance myresourceInstance = buildResourceInstance(softwareComponentResource.getUniqueId(), "1", + "tosca.nodes.test.root"); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + + assertTrue("check instance added to service", myinstanceRes.isLeft()); + + // resource2 + ComponentInstance computeInstance = buildResourceInstance(compute.getUniqueId(), "2", + "tosca.nodes.test.compute"); + ComponentInstance value1 = myinstanceRes.left().value(); + + Either computeInstTes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "2", true, computeInstance, + NodeTypeEnum.Resource, false); + assertTrue("check instance added to service", computeInstTes.isLeft()); + ComponentInstance value2 = computeInstTes.left().value(); + + RequirementAndRelationshipPair relationPair = new RequirementAndRelationshipPair(); + relationPair.setRequirement(reqName); + relationPair.setCapability(capabilityTypeName); + + String capId = ""; + Map> capabilities = compute.getCapabilities(); + for (Map.Entry> entry : capabilities.entrySet()) { + capId = entry.getValue().get(0).getUniqueId(); + } + relationPair.setCapabilityUid(capId); + Map> requirements = softwareComponentResource.getRequirements(); + String reqId = ""; + for (Map.Entry> entry : requirements.entrySet()) { + reqId = entry.getValue().get(0).getUniqueId(); + } + relationPair.setRequirementUid(reqId); + relationPair.setRequirementOwnerId(value1.getUniqueId()); + relationPair.setCapabilityOwnerId(value2.getUniqueId()); + relationPair.setCapabilityUid(capId); + + Either connectResourcesInService = resourceInstanceOperation + .connectResourcesInService(serviceId, NodeTypeEnum.Service, value1.getUniqueId(), value2.getUniqueId(), + relationPair); + + assertTrue("check relation created", connectResourcesInService.isLeft()); + + } + + @Test + public void addResourceInstancesResourceDeleted() { + + String rootName = "tosca.nodes.test.root"; + String softwareCompName = "tosca.nodes.test.softwarecomponent"; + String capabilityTypeName = "myCapability"; + String reqName = "host"; + String computeNodeName = "tosca.nodes.test.compute"; + String reqRelationship = "myRelationship"; + + ServiceMetadataData origService = createService("myService"); + String serviceId = (String) origService.getUniqueId(); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource rootResource = createRootResource(rootName, resourceOperationTest); + // Create Capability type + CapabilityTypeOperationTest capabilityTypeOperationTest = new CapabilityTypeOperationTest(); + capabilityTypeOperationTest.setOperations(titanDao, capabilityTypeOperation); + capabilityTypeOperationTest.createCapability(capabilityTypeName); + + Resource softwareComponentResource = createSoftwareComponentWithReq(softwareCompName, resourceOperationTest, + rootResource, capabilityTypeName, reqName, reqRelationship, computeNodeName); + + deleteResource(softwareComponentResource.getUniqueId()); + + // resource1 + ComponentInstance myresourceInstance = buildResourceInstance(softwareComponentResource.getUniqueId(), "1", + "tosca.nodes.test.root"); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + + assertTrue("check instance not added to service", myinstanceRes.isRight()); + + } + + @Test + public void testDeploymentArtifactsOnRI() { + + String rootName = "tosca.nodes.test.root"; + + ServiceMetadataData origService = createService("testDeploymentArtifactsOnRI"); + String serviceId = (String) origService.getUniqueId(); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource rootResource = createRootResource(rootName, resourceOperationTest); + ArtifactDefinition addArtifactToResource = addArtifactToResource(USER_ID, rootResource.getUniqueId(), + "myArtifact"); + + // resource1 + ComponentInstance myresourceInstance = buildResourceInstance(rootResource.getUniqueId(), "1", rootName); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + + assertTrue("check instance added to service", myinstanceRes.isLeft()); + + Either, List>, TitanOperationStatus> resourceInstancesOfService = resourceInstanceOperation + .getComponentInstancesOfComponent(serviceId, NodeTypeEnum.Service, NodeTypeEnum.Resource); + assertTrue(resourceInstancesOfService.isLeft()); + List resourceInstanceList = resourceInstancesOfService.left().value().left; + assertTrue(resourceInstanceList.size() == 1); + ComponentInstance resourceInstance = resourceInstanceList.get(0); + assertTrue(resourceInstance.getDeploymentArtifacts().size() == 1); + Map artifacts = resourceInstance.getDeploymentArtifacts(); + assertNotNull(artifacts.get(addArtifactToResource.getArtifactLabel())); + + ArtifactDefinition heatEnvArtifact = new ArtifactDefinition(addArtifactToResource); + heatEnvArtifact.setArtifactType("HEAT_ENV"); + heatEnvArtifact.setArtifactLabel(addArtifactToResource.getArtifactLabel() + "env"); + heatEnvArtifact.setUniqueId(null); + + Either either = artifactOperation.addHeatEnvArtifact( + heatEnvArtifact, addArtifactToResource, resourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, + false); + assertTrue(either.isLeft()); + + resourceInstancesOfService = resourceInstanceOperation.getComponentInstancesOfComponent(serviceId, + NodeTypeEnum.Service, NodeTypeEnum.Resource); + assertTrue(resourceInstancesOfService.isLeft()); + resourceInstanceList = resourceInstancesOfService.left().value().left; + assertTrue(resourceInstanceList.size() == 1); + resourceInstance = resourceInstanceList.get(0); + assertTrue(resourceInstance.getDeploymentArtifacts().size() == 2); + artifacts = resourceInstance.getDeploymentArtifacts(); + assertNotNull(artifacts.get(addArtifactToResource.getArtifactLabel())); + assertNotNull(artifacts.get(addArtifactToResource.getArtifactLabel() + "env")); + ArtifactDefinition heatEnvFromRI = artifacts.get(addArtifactToResource.getArtifactLabel() + "env"); + assertEquals(addArtifactToResource.getUniqueId(), heatEnvFromRI.getGeneratedFromId()); + + List heatParameters = artifacts.get(addArtifactToResource.getArtifactLabel()) + .getHeatParameters(); + assertNotNull(heatParameters); + assertTrue(heatParameters.size() == 1); + + List heatEnvParameters = heatEnvFromRI.getHeatParameters(); + assertNotNull(heatEnvParameters); + assertTrue(heatEnvParameters.size() == 1); + + resourceOperation.deleteResource(rootResource.getUniqueId()); + + } + + @Test + public void deleteResourceInstanceWithArtifacts() { + String rootName = "tosca.nodes.test.root"; + + ServiceMetadataData origService = createService("deleteResourceInstanceWithArtifacts"); + String serviceId = (String) origService.getUniqueId(); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource rootResource = createRootResource(rootName, resourceOperationTest); + ArtifactDefinition addArtifactToResource = addArtifactToResource(USER_ID, rootResource.getUniqueId(), + "myArtifact"); + + // resource1 + ComponentInstance myresourceInstance = buildResourceInstance(rootResource.getUniqueId(), "1", rootName); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + + ArtifactDefinition heatEnvArtifact = new ArtifactDefinition(addArtifactToResource); + heatEnvArtifact.setArtifactType("HEAT_ENV"); + heatEnvArtifact.setArtifactLabel(addArtifactToResource.getArtifactLabel() + "env"); + heatEnvArtifact.setUniqueId(null); + + assertTrue("check instance added to service", myinstanceRes.isLeft()); + + Either, List>, TitanOperationStatus> resourceInstancesOfService = resourceInstanceOperation + .getComponentInstancesOfComponent(serviceId, NodeTypeEnum.Service, NodeTypeEnum.Resource); + assertTrue(resourceInstancesOfService.isLeft()); + List resourceInstanceList = resourceInstancesOfService.left().value().left; + assertTrue(resourceInstanceList.size() == 1); + ComponentInstance resourceInstance = resourceInstanceList.get(0); + + Either either = artifactOperation.addHeatEnvArtifact( + heatEnvArtifact, addArtifactToResource, resourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, + false); + assertTrue(either.isLeft()); + ArtifactDefinition heatEnvDefinition = either.left().value(); + + // delete resource instance + Either deleteResourceInstance = resourceInstanceOperation + .deleteComponentInstance(NodeTypeEnum.Service, serviceId, resourceInstance.getUniqueId()); + assertTrue(deleteResourceInstance.isLeft()); + + // check heat env deleted + ArtifactData artifactData = new ArtifactData(); + Either getDeletedArtifact = titanDao.getNode(artifactData.getUniqueIdKey(), + heatEnvDefinition.getUniqueId(), ArtifactData.class); + assertTrue(getDeletedArtifact.isRight()); + + // check heat is not deleted + getDeletedArtifact = titanDao.getNode(artifactData.getUniqueIdKey(), addArtifactToResource.getUniqueId(), + ArtifactData.class); + assertTrue(getDeletedArtifact.isLeft()); + + HeatParameterData heatParamData = new HeatParameterData(); + Either heatParamNode = titanDao.getNode(heatParamData.getUniqueIdKey(), + addArtifactToResource.getHeatParameters().get(0).getUniqueId(), HeatParameterData.class); + assertTrue(heatParamNode.isLeft()); + + resourceOperation.deleteResource(rootResource.getUniqueId()); + + } + + @Test + public void getHeatEnvParams() { + String rootName = "tosca.nodes.test.root"; + + ServiceMetadataData origService = createService("getHeatEnvParams"); + String serviceId = (String) origService.getUniqueId(); + + ResourceOperationTest resourceOperationTest = new ResourceOperationTest(); + resourceOperationTest.setOperations(titanDao, resourceOperation, propertyOperation); + + Resource rootResource = createRootResource(rootName, resourceOperationTest); + ArtifactDefinition addArtifactToResource = addArtifactToResource(USER_ID, rootResource.getUniqueId(), + "myArtifact"); + + // resource1 + ComponentInstance myresourceInstance = buildResourceInstance(rootResource.getUniqueId(), "1", rootName); + + Either myinstanceRes = resourceInstanceOperation + .addComponentInstanceToContainerComponent(serviceId, NodeTypeEnum.Service, "1", true, + myresourceInstance, NodeTypeEnum.Resource, false); + + ArtifactDefinition heatEnvArtifact = new ArtifactDefinition(addArtifactToResource); + heatEnvArtifact.setArtifactType("HEAT_ENV"); + heatEnvArtifact.setArtifactLabel(addArtifactToResource.getArtifactLabel() + "env"); + heatEnvArtifact.setUniqueId(null); + + assertTrue("check instance added to service", myinstanceRes.isLeft()); + + Either, List>, TitanOperationStatus> resourceInstancesOfService = resourceInstanceOperation + .getComponentInstancesOfComponent(serviceId, NodeTypeEnum.Service, NodeTypeEnum.Resource); + assertTrue(resourceInstancesOfService.isLeft()); + List resourceInstanceList = resourceInstancesOfService.left().value().left; + assertTrue(resourceInstanceList.size() == 1); + ComponentInstance resourceInstance = resourceInstanceList.get(0); + + Either either = artifactOperation.addHeatEnvArtifact( + heatEnvArtifact, addArtifactToResource, resourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, + false); + assertTrue(either.isLeft()); + ArtifactDefinition heatEnvDefinition = either.left().value(); + + // update value + String newHeatValue = "123"; + addHeatValueToEnv(heatEnvDefinition.getUniqueId(), addArtifactToResource.getHeatParameters().get(0), + newHeatValue); + + // check values received + + resourceInstancesOfService = resourceInstanceOperation.getComponentInstancesOfComponent(serviceId, + NodeTypeEnum.Service, NodeTypeEnum.Resource); + assertTrue(resourceInstancesOfService.isLeft()); + resourceInstanceList = resourceInstancesOfService.left().value().left; + assertTrue(resourceInstanceList.size() == 1); + resourceInstance = resourceInstanceList.get(0); + assertTrue(resourceInstance.getDeploymentArtifacts().size() == 2); + Map artifacts = resourceInstance.getDeploymentArtifacts(); + assertNotNull(artifacts.get(addArtifactToResource.getArtifactLabel())); + assertNotNull(artifacts.get(addArtifactToResource.getArtifactLabel() + "env")); + + List heatParameters = artifacts.get(addArtifactToResource.getArtifactLabel()) + .getHeatParameters(); + assertNotNull(heatParameters); + assertTrue(heatParameters.size() == 1); + HeatParameterDefinition heatParameterTemplate = heatParameters.get(0); + + List heatEnvParameters = artifacts + .get(addArtifactToResource.getArtifactLabel() + "env").getHeatParameters(); + assertNotNull(heatEnvParameters); + assertTrue(heatEnvParameters.size() == 1); + HeatParameterDefinition heatParameterEnv = heatEnvParameters.get(0); + + assertEquals(heatParameterEnv.getDefaultValue(), heatParameterTemplate.getCurrentValue()); + assertEquals(newHeatValue, heatParameterEnv.getCurrentValue()); + assertFalse(newHeatValue.equals(heatParameterTemplate.getCurrentValue())); + + resourceOperation.deleteResource(rootResource.getUniqueId()); + + } + + public void addHeatValueToEnv(String artifactId, HeatParameterDefinition heatDefinition, String value) { + HeatParameterValueData heatValueData = new HeatParameterValueData(); + heatValueData.setValue(value); + heatValueData.setUniqueId(artifactId + "." + heatDefinition.getName()); + Either createValue = titanDao.createNode(heatValueData, + HeatParameterValueData.class); + assertTrue(createValue.isLeft()); + HeatParameterValueData value2 = createValue.left().value(); + HeatParameterData heatParamData = new HeatParameterData(heatDefinition); + Either createRelation = titanDao.createRelation(value2, heatParamData, + GraphEdgeLabels.PROPERTY_IMPL, null); + assertTrue(createRelation.isLeft()); + Map props = new HashMap(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), heatDefinition.getName()); + Either createRelation2 = titanDao.createRelation( + new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId), value2, GraphEdgeLabels.PARAMETER_VALUE, props); + assertTrue(createRelation2.isLeft()); + titanDao.commit(); + + } + + public static String normaliseComponentName(String name) { + String[] split = splitComponentName(name); + StringBuffer sb = new StringBuffer(); + for (String splitElement : split) { + sb.append(splitElement); + } + return sb.toString(); + + } + + private static String[] splitComponentName(String name) { + String normalizedName = name.toLowerCase(); + normalizedName = COMPONENT_NAME_DELIMETER_PATTERN.matcher(normalizedName).replaceAll(" "); + String[] split = normalizedName.split(" "); + return split; + } + + public static String normaliseComponentInstanceName(String name) { + String[] split = splitComponentInstanceName(name); + StringBuffer sb = new StringBuffer(); + for (String splitElement : split) { + sb.append(splitElement); + } + return sb.toString(); + + } + + private static String[] splitComponentInstanceName(String name) { + String normalizedName = name.toLowerCase(); + normalizedName = COMPONENT_INCTANCE_NAME_DELIMETER_PATTERN.matcher(normalizedName).replaceAll(" "); + String[] split = normalizedName.split(" "); + return split; + } + + private ArtifactDefinition addArtifactToResource(String userId, String resourceId, String artifactName) { + ArtifactDefinition artifactInfo = new ArtifactDefinition(); + + artifactInfo.setArtifactName(artifactName + ".yml"); + artifactInfo.setArtifactType("HEAT"); + artifactInfo.setDescription("hdkfhskdfgh"); + artifactInfo.setArtifactChecksum("UEsDBAoAAAAIAAeLb0bDQz"); + artifactInfo.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); + + artifactInfo.setUserIdCreator(userId); + String fullName = "Jim H"; + artifactInfo.setUpdaterFullName(fullName); + long time = System.currentTimeMillis(); + artifactInfo.setCreatorFullName(fullName); + artifactInfo.setCreationDate(time); + artifactInfo.setLastUpdateDate(time); + artifactInfo.setUserIdLastUpdater(userId); + artifactInfo.setArtifactLabel(artifactName); + artifactInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel())); + artifactInfo.setEsId(artifactInfo.getUniqueId()); + + List heatParams = new ArrayList(); + HeatParameterDefinition heatParam = new HeatParameterDefinition(); + heatParam.setCurrentValue("11"); + heatParam.setDefaultValue("22"); + heatParam.setDescription("desc"); + heatParam.setName("myParam"); + heatParam.setType("number"); + heatParams.add(heatParam); + artifactInfo.setHeatParameters(heatParams); + + Either artifact = artifactOperation + .addArifactToComponent(artifactInfo, resourceId, NodeTypeEnum.Resource, true, true); + assertTrue(artifact.isLeft()); + return artifact.left().value(); + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperationTest.java new file mode 100644 index 0000000000..f977509f6b --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperationTest.java @@ -0,0 +1,734 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +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 org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +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.CapabilityDefinition; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.PropertyConstraint; +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.StorageOperationStatus; +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.LifecycleOperation; +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.impl.util.OperationTestsUtil; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class ResourceOperationTest extends ModelTestBase { + + private static Logger log = LoggerFactory.getLogger(ResourceOperationTest.class.getName()); + @javax.annotation.Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + @javax.annotation.Resource(name = "resource-operation") + private ResourceOperation resourceOperation; + + @javax.annotation.Resource(name = "property-operation") + private PropertyOperation propertyOperation; + + @javax.annotation.Resource(name = "lifecycle-operation") + private LifecycleOperation lifecycleOperation; + + @javax.annotation.Resource(name = "capability-operation") + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource(name = "capability-type-operation") + private CapabilityTypeOperation capabilityTypeOperation; + + private static String CATEGORY_NAME = "category/mycategory"; + private static String CATEGORY_NAME_UPDATED = "category1/updatedcategory"; + + @BeforeClass + public static void setupBeforeClass() { + + ModelTestBase.init(); + } + + public void setOperations(TitanGenericDao titanGenericDao, ResourceOperation resourceOperation, + PropertyOperation propertyOperation) { + this.titanDao = titanGenericDao; + this.resourceOperation = resourceOperation; + this.propertyOperation = propertyOperation; + } + + @Test + public void dummyTest() { + + } + + private Resource buildResourceMetadata(String userId, String category, String resourceName, + String resourceVersion) { + + Resource resource = new Resource(); + resource.setName(resourceName); + resource.setVersion(resourceVersion); + ; + resource.setDescription("description 1"); + resource.setAbstract(false); + resource.setCreatorUserId(userId); + resource.setContactId("contactId@sdc.com"); + resource.setVendorName("vendor 1"); + resource.setVendorRelease("1.0.0"); + resource.setToscaResourceName(resourceName); + String[] categoryArr = category.split("/"); + resource.addCategory(categoryArr[0], categoryArr[1]); + resource.setIcon("images/my.png"); + List tags = new ArrayList(); + tags.add("TAG1"); + tags.add("TAG2"); + resource.setTags(tags); + return resource; + } + + private UserData deleteAndCreateUser(String userId, String firstName, String lastName) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + + titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanDao.createNode(userData, UserData.class); + titanDao.commit(); + + return userData; + } + + private void deleteAndCreateCategory(String category) { + String[] names = category.split("/"); + OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao); + } + + public Resource createResource(String userId, String category, String resourceName, String resourceVersion, + String parentResourceName, boolean isAbstract, boolean isHighestVersion) { + + String propName1 = "disk_size"; + String propName2 = "num_cpus"; + + List derivedFrom = new ArrayList(); + if (parentResourceName != null) { + derivedFrom.add(parentResourceName); + } + Resource resource = buildResourceMetadata(userId, category, resourceName, resourceVersion); + + resource.setAbstract(isAbstract); + resource.setHighestVersion(isHighestVersion); + + Map properties = new HashMap(); + + PropertyDefinition property1 = new PropertyDefinition(); + property1.setDefaultValue("10"); + property1.setDescription( + "Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node."); + property1.setType(ToscaType.INTEGER.name().toLowerCase()); + List constraints = new ArrayList(); + GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0"); + log.debug("{}", propertyConstraint1); + + constraints.add(propertyConstraint1); + + LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10"); + constraints.add(propertyConstraint2); + + property1.setConstraints(constraints); + + properties.put(propName1, property1); + + PropertyDefinition property2 = new PropertyDefinition(); + property2.setDefaultValue("2"); + property2.setDescription("Number of (actual or virtual) CPUs associated with the Compute node."); + property2.setType(ToscaType.INTEGER.name().toLowerCase()); + List constraints3 = new ArrayList(); + List range = new ArrayList(); + range.add("1"); + range.add("4"); + + InRangeConstraint propertyConstraint3 = new InRangeConstraint(range); + constraints3.add(propertyConstraint3); + // property2.setConstraints(constraints3); + property2.setConstraints(constraints3); + properties.put(propName2, property2); + + resource.setDerivedFrom(derivedFrom); + + resource.setProperties(convertMapToList(properties)); + + Either result = resourceOperation.createResource(resource, true); + + assertTrue(result.isLeft()); + Resource resultResource = result.left().value(); + + // assertEquals("check resource unique id", + // UniqueIdBuilder.buildResourceUniqueId(resourceName, + // resourceVersion), resultResource.getUniqueId()); + assertEquals("check resource state", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + resultResource.getLifecycleState()); + + // retrieve property from graph + String resourceId = resultResource.getUniqueId(); + // String resourceId = UniqueIdBuilder.buildResourceUniqueId( + // resource.getResourceName(), resource.getResourceVersion()); + + Either either = propertyOperation.getPropertyOfResource(propName1, + resourceId); + + assertTrue(either.isLeft()); + PropertyDefinition propertyDefinition = either.left().value(); + assertEquals("check property default value", property1.getDefaultValue(), propertyDefinition.getDefaultValue()); + assertEquals("check property description", property1.getDescription(), propertyDefinition.getDescription()); + assertEquals("check property type", property1.getType(), propertyDefinition.getType()); + assertEquals("check property unique id", property1.getUniqueId(), propertyDefinition.getUniqueId()); + assertEquals("check property consitraints size", property1.getConstraints().size(), + propertyDefinition.getConstraints().size()); + + return resultResource; + + } + + 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; + } + + @Test + public void testFollowed() { + String rootName = "Root123"; + + String userId = "jh0003"; + String category = CATEGORY_NAME; + deleteAndCreateUser(userId, "first_" + userId, "last_" + userId); + deleteAndCreateCategory(category); + + Resource rootResource = createResource(userId, category, rootName, "1.0", null, false, true); + log.debug(" *** create **"); + log.debug("{}", rootResource); + String resourceId = rootResource.getUniqueId(); + + Set lifecycleStates = new HashSet(); + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + Set lastStateStates = new HashSet(); + lastStateStates.add(LifecycleStateEnum.CERTIFIED); + + Either, StorageOperationStatus> followed = resourceOperation.getFollowed(userId, lifecycleStates, + lastStateStates, false); + assertTrue(followed.isLeft()); + List list = followed.left().value(); + + assertEquals(1, list.size()); + resourceOperation.deleteResource(resourceId); + + followed = resourceOperation.getFollowed(userId, lifecycleStates, lastStateStates, false); + assertTrue(followed.isLeft()); + list = followed.left().value(); + assertTrue(list.isEmpty()); + + } + + @Ignore + @Test + public void testGetLatestVersion() { + String rootName = "Root123"; + + String userId = "jh0003"; + String category = "category/mycategory"; + deleteAndCreateUser(userId, "first_" + userId, "last_" + userId); + deleteAndCreateCategory(category); + + Either latestByName = resourceOperation.getLatestByName(rootName, true); + assertTrue(latestByName.isRight()); + assertEquals(StorageOperationStatus.NOT_FOUND, latestByName.right().value()); + + Resource rootResource = createResource(userId, category, rootName, "1.0", null, false, true); + + latestByName = resourceOperation.getLatestByName(rootName, true); + assertTrue(latestByName.isLeft()); + + Resource rootResourceHighest = createResource(userId, category, rootName, "1.3", null, false, true); + + latestByName = resourceOperation.getLatestByName(rootName, false); + assertTrue(latestByName.isLeft()); + assertEquals(rootResourceHighest.getUniqueId(), latestByName.left().value().getUniqueId()); + + resourceOperation.deleteResource(rootResource.getUniqueId()); + resourceOperation.deleteResource(rootResourceHighest.getUniqueId()); + } + + @Test + public void testOverrideResource() { + String rootName = "Root123"; + + String userId = "jh0003"; + String category = CATEGORY_NAME; + String updatedCategory = CATEGORY_NAME_UPDATED; + deleteAndCreateUser(userId, "first_" + userId, "last_" + userId); + deleteAndCreateCategory(category); + deleteAndCreateCategory(updatedCategory); + + Resource rootResource = createResource(userId, category, rootName, "1.1", null, false, true); + + rootResource.setCategories(null); + String[] updateArr = updatedCategory.split("/"); + rootResource.addCategory(updateArr[0], updateArr[1]); + List properties = rootResource.getProperties(); + PropertyDefinition propertyDefinition = findProperty(properties, "disk_size"); + + rootResource.setProperties(new ArrayList()); + propertyDefinition.setName("myProperty"); + rootResource.getProperties().add(propertyDefinition); + + Either overrideResource = resourceOperation.overrideResource(rootResource, + rootResource, false); + + assertTrue(overrideResource.isLeft()); + Resource resourceAfter = overrideResource.left().value(); + assertEquals(1, resourceAfter.getProperties().size()); + + assertNotNull(findProperty(resourceAfter.getProperties(), "myProperty")); + assertEquals(1, resourceAfter.getCategories().size()); + assertEquals(1, resourceAfter.getCategories().get(0).getSubcategories().size()); + + assertEquals(updateArr[0], resourceAfter.getCategories().get(0).getName()); + assertEquals(updateArr[1], resourceAfter.getCategories().get(0).getSubcategories().get(0).getName()); + + resourceOperation.deleteResource(rootResource.getUniqueId()); + } + + @Test + public void testResourceWithCapabilities() { + String rootName = "Root123"; + + String userId = "jh0003"; + String category = CATEGORY_NAME; + String updatedCategory = CATEGORY_NAME_UPDATED; + deleteAndCreateUser(userId, "first_" + userId, "last_" + userId); + deleteAndCreateCategory(category); + deleteAndCreateCategory(updatedCategory); + + Resource rootResource = createResource(userId, category, rootName, "1.1", null, false, true); + + CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(); + capabilityTypeDefinition.setType("tosca.capabilities.Container"); + PropertyDefinition delaultProperty1 = new PropertyDefinition(); + delaultProperty1.setName("def"); + delaultProperty1.setType("string"); + delaultProperty1.setDefaultValue("def"); + + PropertyDefinition delaultProperty2 = new PropertyDefinition(); + delaultProperty2.setName("host"); + delaultProperty2.setType("string"); + delaultProperty2.setDefaultValue("true"); + + HashMap props = new HashMap(); + props.put(delaultProperty1.getName(), delaultProperty1); + props.put(delaultProperty2.getName(), delaultProperty2); + capabilityTypeDefinition.setProperties(props); + + Either addTypeRes = capabilityTypeOperation + .addCapabilityType(capabilityTypeDefinition); + assertTrue(addTypeRes.isLeft()); + + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setDescription("firstCap"); + capabilityDefinition.setName("firstCap"); + capabilityDefinition.setType("tosca.capabilities.Container"); + + List properties = new ArrayList(); + ComponentInstanceProperty propertyDefinition1 = new ComponentInstanceProperty(); + propertyDefinition1.setName("version"); + propertyDefinition1.setType("string"); + propertyDefinition1.setDefaultValue("007"); + properties.add(propertyDefinition1); + + ComponentInstanceProperty propertyDefinition2 = new ComponentInstanceProperty(); + propertyDefinition2.setName("host"); + propertyDefinition2.setType("string"); + propertyDefinition2.setDefaultValue("localhost"); + properties.add(propertyDefinition2); + + capabilityDefinition.setProperties(properties); + + Either addCapabilityRes = capabilityOperation + .addCapability(rootResource.getUniqueId(), capabilityDefinition.getName(), capabilityDefinition); + assertTrue(addCapabilityRes.isLeft()); + + List newProperties = new ArrayList(); + propertyDefinition1 = new ComponentInstanceProperty(); + propertyDefinition1.setName("num_cpu"); + propertyDefinition1.setType("string"); + propertyDefinition1.setDefaultValue("4"); + newProperties.add(propertyDefinition1); + + propertyDefinition2 = new ComponentInstanceProperty(); + propertyDefinition2.setName("port"); + propertyDefinition2.setType("string"); + propertyDefinition2.setDefaultValue("4444"); + newProperties.add(propertyDefinition2); + + CapabilityDefinition addedCap = addCapabilityRes.left().value(); + + Either, StorageOperationStatus> updatePropertiesRes = capabilityOperation + .updatePropertiesOfCapability(addedCap.getUniqueId(), addedCap.getType(), newProperties); + assertTrue(updatePropertiesRes.isLeft()); + + PropertyDefinition invalidProperty = new PropertyDefinition(); + invalidProperty.setName("port"); + invalidProperty.setType("rrr"); + invalidProperty.setDefaultValue("666"); + newProperties.add(invalidProperty); + + Either, StorageOperationStatus> updatePropertiesInvalidRes = capabilityOperation + .updatePropertiesOfCapability(addedCap.getUniqueId(), addedCap.getType(), newProperties); + assertTrue(updatePropertiesInvalidRes.isRight()); + + Either getCapabilityRes = capabilityOperation + .getCapability(addedCap.getUniqueId()); + assertTrue(getCapabilityRes.isLeft()); + + Either>, TitanOperationStatus> deletePropertiesOfCapabilityRes = capabilityOperation + .deletePropertiesOfCapability(addedCap.getUniqueId()); + assertTrue(deletePropertiesOfCapabilityRes.isLeft()); + + StorageOperationStatus deleteCapabilityRes = capabilityOperation + .deleteCapabilityFromGraph(addedCap.getUniqueId()); + assertTrue(deleteCapabilityRes.equals(StorageOperationStatus.OK)); + + getCapabilityRes = capabilityOperation.getCapability(addedCap.getUniqueId()); + assertTrue(getCapabilityRes.isRight() + && getCapabilityRes.right().value().equals(StorageOperationStatus.NOT_FOUND)); + + resourceOperation.deleteResource(rootResource.getUniqueId()); + } + + private PropertyDefinition findProperty(List properties, String propName) { + + if (properties == null) { + return null; + } + + for (PropertyDefinition propertyDefinition : properties) { + String name = propertyDefinition.getName(); + if (name.equals(propName)) { + return propertyDefinition; + } + } + + return null; + } + + @Test + public void testOverrideResourceNotExist() { + String rootName = "Root123"; + + String userId = "jh0003"; + String category = CATEGORY_NAME; + deleteAndCreateUser(userId, "first_" + userId, "last_" + userId); + deleteAndCreateCategory(category); + + Resource rootResource = buildResourceMetadata(userId, category, rootName, "1.1"); + rootResource.setUniqueId(UniqueIdBuilder.buildResourceUniqueId()); + + Either overrideResource = resourceOperation.overrideResource(rootResource, + rootResource, false); + + assertTrue(overrideResource.isRight()); + + } + + @Ignore + @Test + public void testCatalogResource() { + String resName = "myResource"; + String userId = "jh0003"; + String category = CATEGORY_NAME; + deleteAndCreateCategory(category); + // resourceOperation.deleteResource(UniqueIdBuilder.buildResourceUniqueId(resName,"0.1")); + Resource newResource = createResource(userId, category, resName, "0.1", null, false, true); + String resourceId = newResource.getUniqueId(); + + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + Either, StorageOperationStatus> catalog = resourceOperation.getCatalogData(propertiesToMatch, + false); + assertTrue(catalog.isLeft()); + Set catalogSet = catalog.left().value(); + Set idSet = new HashSet<>(); + for (Resource resource : catalogSet) { + idSet.add(resource.getUniqueId()); + } + assertTrue(idSet.contains(resourceId)); + resourceOperation.deleteResource(resourceId); + } + + @Ignore + @Test + public void testTesterFollowed() { + String rootName = "Test1"; + String rootName2 = "Test2"; + String rootName3 = "Test3"; + String userId = "jh0003"; + String testerUserId = "tt0004"; + String category = CATEGORY_NAME; + deleteAndCreateUser(testerUserId, "tester", "last"); + deleteAndCreateCategory(category); + + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + Either findUser = titanDao.getNode(key, userId, UserData.class); + User adminUser = OperationTestsUtil.convertUserDataToUser(findUser.left().value()); + Either findTesterUser = titanDao.getNode(key, testerUserId, UserData.class); + User testerUser = OperationTestsUtil.convertUserDataToUser(findTesterUser.left().value()); + + // Create 3 new resources + Resource resultResource = createResource(userId, category, rootName, "1.0", null, false, true); + log.debug("{}", resultResource); + String resourceId = resultResource.getUniqueId(); + Resource resultResource2 = createResource(userId, category, rootName2, "1.0", null, false, true); + log.debug("{}", resultResource2); + String resourceId2 = resultResource2.getUniqueId(); + Resource resultResource3 = createResource(userId, category, rootName3, "1.0", null, false, true); + log.debug("{}", resultResource3); + String resourceId3 = resultResource3.getUniqueId(); + + // update 1 resource to READY_FOR_CERTIFICATION + Either certReqResponse = (Either) lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Resource, resultResource, adminUser, adminUser, false); + Resource RFCResource = certReqResponse.left().value(); + assertEquals(RFCResource.getLifecycleState(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + + // update 1 resource to CERTIFICATION_IN_PROGRESS + Either startCertificationResponse = (Either) lifecycleOperation + .startComponentCertification(NodeTypeEnum.Resource, resultResource2, testerUser, adminUser, false); + Resource IPResource = startCertificationResponse.left().value(); + assertEquals(IPResource.getLifecycleState(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + Set lifecycleStates = new HashSet(); + lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + Either, StorageOperationStatus> resources = resourceOperation.getTesterFollowed(testerUserId, + lifecycleStates, false); + + assertTrue(resources.isLeft()); + List result = resources.left().value(); + + List idSet = new ArrayList(); + for (Resource resource : result) { + idSet.add(resource.getUniqueId()); + } + assertTrue(idSet.contains(resourceId)); + assertTrue(idSet.contains(resourceId2)); + assertFalse(idSet.contains(resourceId3)); + resourceOperation.deleteResource(resourceId); + resourceOperation.deleteResource(resourceId2); + resourceOperation.deleteResource(resourceId3); + + } + + @Test + public void getVersionListNotDeleted() { + String resName = "myResource"; + String userId = "jh0003"; + String category = CATEGORY_NAME; + deleteAndCreateCategory(category); + + Resource newResource = createResource(userId, category, resName, "0.1", null, false, true); + String resourceId1 = newResource.getUniqueId(); + + User admin = new User("j", "h", userId, null, "ADMIN", System.currentTimeMillis()); + Either checkoutResource = (Either) lifecycleOperation + .checkoutComponent(NodeTypeEnum.Resource, newResource, admin, admin, false); + assertTrue(checkoutResource.isLeft()); + Resource newResource2 = checkoutResource.left().value(); + String resourceId2 = newResource2.getUniqueId(); + + Resource newResource3 = createResource(userId, category, resName, "0.1", null, false, true); + String resourceId3 = newResource3.getUniqueId(); + + Either, TitanOperationStatus> versionList = resourceOperation.getVersionList( + NodeTypeEnum.Resource, "0.2", newResource2.getUUID(), newResource2.getSystemName(), + ResourceMetadataData.class); + assertTrue(versionList.isLeft()); + Map versionMap = versionList.left().value(); + + assertTrue(versionMap.size() == 2); + assertTrue(versionMap.containsValue(resourceId1)); + assertTrue(versionMap.containsValue(resourceId2)); + assertFalse(versionMap.containsValue(resourceId3)); + + Either deleteResource = resourceOperation.deleteResource(resourceId1); + assertTrue(deleteResource.isLeft()); + deleteResource = resourceOperation.deleteResource(resourceId2); + assertTrue(deleteResource.isLeft()); + deleteResource = resourceOperation.deleteResource(resourceId3); + assertTrue(deleteResource.isLeft()); + + } + + @Test + public void getVersionListWithDeleted() { + String resName = "myResource"; + String userId = "jh0003"; + String category = CATEGORY_NAME; + deleteAndCreateCategory(category); + + Resource newResource = createResource(userId, category, resName, "0.1", null, false, true); + String resourceId1 = newResource.getUniqueId(); + + User admin = new User("j", "h", userId, null, "ADMIN", System.currentTimeMillis()); + Either checkoutResource = (Either) lifecycleOperation + .checkoutComponent(NodeTypeEnum.Resource, newResource, admin, admin, false); + assertTrue(checkoutResource.isLeft()); + Resource newResource2 = checkoutResource.left().value(); + String resourceId2 = newResource2.getUniqueId(); + + Either resource = resourceOperation.getResource(resourceId1, false); + assertTrue(resource.isLeft()); + Either markResourceToDelete = resourceOperation + .markComponentToDelete(resource.left().value(), false); + assertTrue(markResourceToDelete.isLeft()); + + Either, TitanOperationStatus> versionList = resourceOperation.getVersionList( + NodeTypeEnum.Resource, "0.2", newResource2.getUUID(), newResource2.getSystemName(), + ResourceMetadataData.class); + + assertTrue(versionList.isLeft()); + Map versionMap = versionList.left().value(); + + assertTrue(versionMap.size() == 1); + assertFalse(versionMap.containsValue(resourceId1)); + assertTrue(versionMap.containsValue(resourceId2)); + + Either deleteResource = resourceOperation.deleteResource(resourceId1); + assertTrue(deleteResource.isLeft()); + deleteResource = resourceOperation.deleteResource(resourceId2); + assertTrue(deleteResource.isLeft()); + } + + @Test + public void testDerviedPropertiesInResource() { + + try { + String userId = "jh0003"; + String category = CATEGORY_NAME; + + deleteAndCreateUser(userId, "first_" + userId, "last_" + userId); + deleteAndCreateCategory(category); + + Resource createResource1 = createResource(userId, category, "myResource1", "0.1", null, true, false); + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(createResource1.getUniqueId()); + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.CERTIFIED.name()); + Either updateNode = titanDao.updateNode(resourceData, + ResourceMetadataData.class); + assertTrue(updateNode.isLeft()); + + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + String json = gson.toJson(createResource1); + log.debug(json); + + Resource createResource2 = createResource(userId, category, "myResource2", "0.1", createResource1.getName(), + true, false); + + json = gson.toJson(createResource2); + log.debug(json); + + List propList1 = new ArrayList<>(); + TitanOperationStatus findAllResourcePropertiesRecursively1 = propertyOperation + .findAllResourcePropertiesRecursively(createResource1.getUniqueId(), propList1); + assertEquals("check search properties succeed", findAllResourcePropertiesRecursively1, + TitanOperationStatus.OK); + + List propList2 = new ArrayList<>(); + TitanOperationStatus findAllResourcePropertiesRecursively2 = propertyOperation + .findAllResourcePropertiesRecursively(createResource2.getUniqueId(), propList2); + assertEquals("check search properties succeed", findAllResourcePropertiesRecursively2, + TitanOperationStatus.OK); + + assertEquals("check number of properties", propList1.size() * 2, propList2.size()); + + resourceOperation.deleteResource(createResource1.getUniqueId()); + resourceOperation.deleteResource(createResource2.getUniqueId()); + + } finally { + + } + + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperationTest.java new file mode 100644 index 0000000000..81a5a5ed1d --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperationTest.java @@ -0,0 +1,964 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +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.Set; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +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.ArtifactDefinition; +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.ModelTestBase; +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.IGraphLockOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.util.OperationTestsUtil; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thinkaurelius.titan.core.TitanGraph; +//import com.tinkerpop.blueprints.Vertex; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:application-context-test.xml") +public class ServiceOperationTest extends ModelTestBase { + + @javax.annotation.Resource(name = "titan-generic-dao") + private TitanGenericDao titanDao; + + @javax.annotation.Resource(name = "service-operation") + private ServiceOperation serviceOperation; + + @javax.annotation.Resource + private IGraphLockOperation graphLockOperation; + + @javax.annotation.Resource + private ArtifactOperation artifactOperation; + + @javax.annotation.Resource(name = "requirement-operation") + private RequirementOperation requirementOperation; + + @javax.annotation.Resource(name = "resource-operation") + private ResourceOperation resourceOperation; + + @javax.annotation.Resource(name = "property-operation") + private PropertyOperation propertyOperation; + + @javax.annotation.Resource(name = "capability-operation") + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource(name = "capability-type-operation") + private CapabilityTypeOperation capabilityTypeOperation; + + @javax.annotation.Resource(name = "component-instance-operation") + private ComponentInstanceOperation resourceInstanceOperation; + + @javax.annotation.Resource(name = "lifecycle-operation") + private LifecycleOperation lifecycleOperation; + + private static Logger log = LoggerFactory.getLogger(ServiceOperation.class.getName()); + private static String USER_ID = "muserId"; + private static String CATEGORY_NAME = "category/mycategory"; + + @BeforeClass + public static void setupBeforeClass() { + // ExternalConfiguration.setAppName("catalog-model"); + // String appConfigDir = "src/test/resources/config/catalog-model"; + // ConfigurationSource configurationSource = new + // FSConfigurationSource(ExternalConfiguration.getChangeListener(), + // appConfigDir); + + // configurationManager = new ConfigurationManager(new + // ConfigurationSource() { + // + // @Override + // public T getAndWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public void addWatchConfiguration(Class className, + // ConfigurationListener configurationListener) { + // // TODO Auto-generated method stub + // + // } + // }); + + // String appConfigDir = "src/test/resources/config"; + // ConfigurationSource configurationSource = new + // FSConfigurationSource(ExternalConfiguration.getChangeListener(), + // appConfigDir); + // configurationManager = new ConfigurationManager(configurationSource); + // + // Configuration configuration = new Configuration(); + // configuration.setTitanInMemoryGraph(true); + //// configuration.setTitanInMemoryGraph(false); + //// configuration.setTitanCfgFile("C:\\Dev\\d2\\D2-SDnC\\catalog-be\\src\\main\\resources\\config\\titan.properties"); + // + // configurationManager.setConfiguration(configuration); + + ModelTestBase.init(); + } + + @Before + public void createUserAndCategory() { + deleteAndCreateCategory(CATEGORY_NAME); + deleteAndCreateUser(USER_ID, "first_" + USER_ID, "last_" + USER_ID, null); + } + + @Test + public void dummyTest() { + + } + + @Test + public void testCreateService() { + String category = CATEGORY_NAME; + String serviceName = "servceTest"; + String serviceVersion = "0.1"; + String userId = USER_ID; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug(" *** create **"); + log.debug("{}", serviceAfterSave); + String uniqueId = serviceAfterSave.getUniqueId(); + + Either serviceGet = serviceOperation.getService(uniqueId); + assertTrue(serviceGet.isLeft()); + log.debug(" *** get **"); + log.debug("{}", serviceGet.left().value()); + + Either serviceDelete = serviceOperation.deleteService(uniqueId); + + assertTrue(serviceDelete.isLeft()); + log.debug(" *** delete **"); + log.debug("{}", serviceDelete.left().value()); + + Either, TitanOperationStatus> artifacts = titanDao.getByCriteria(NodeTypeEnum.ArtifactRef, + null, ArtifactData.class); + assertTrue(artifacts.isRight()); + assertEquals(TitanOperationStatus.NOT_FOUND, artifacts.right().value()); + + serviceOperation.deleteService(serviceAfterSave.getUniqueId()); + } + + @Test + public void testUtilsService() { + String category = CATEGORY_NAME; + String serviceName = "servceTest2"; + String serviceVersion = "0.1"; + String userId = USER_ID; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug(" *** create **"); + log.debug("{}", serviceAfterSave); + String uniqueId = serviceAfterSave.getUniqueId(); + + boolean canWorkOnComponent = ComponentValidationUtils.canWorkOnComponent(uniqueId, serviceOperation, userId); + assertTrue(canWorkOnComponent); + + canWorkOnComponent = ComponentValidationUtils.canWorkOnComponent(serviceAfterSave, userId); + assertTrue(canWorkOnComponent); + + StorageOperationStatus lockComponent = graphLockOperation.lockComponent(uniqueId, NodeTypeEnum.Service); + assertEquals(StorageOperationStatus.OK, lockComponent); + + lockComponent = graphLockOperation.unlockComponent(uniqueId, NodeTypeEnum.Service); + assertEquals(StorageOperationStatus.OK, lockComponent); + + Either serviceDelete = serviceOperation.deleteService(uniqueId); + } + + @Test + public void testInstanceCounter() { + String category = CATEGORY_NAME; + String serviceName = "servceTest2"; + String serviceVersion = "0.1"; + String userId = USER_ID; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug(" *** create **"); + log.debug("{}", serviceAfterSave); + + Either counter = serviceOperation + .increaseAndGetComponentInstanceCounter(serviceAfterSave.getUniqueId(), NodeTypeEnum.Service, false); + assertTrue(counter.isLeft()); + assertEquals(new Integer(1), (Integer) counter.left().value()); + + counter = serviceOperation.increaseAndGetComponentInstanceCounter(serviceAfterSave.getUniqueId(), + NodeTypeEnum.Service, false); + assertTrue(counter.isLeft()); + assertEquals(new Integer(2), (Integer) counter.left().value()); + Either serviceDelete = serviceOperation + .deleteService(serviceAfterSave.getUniqueId()); + } + + @Test + public void testAddArtifactToService() { + String category = CATEGORY_NAME; + String serviceName = "servceTest2"; + String serviceVersion = "0.1"; + String userId = USER_ID; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug("{}", serviceAfterSave); + String serviceId = serviceAfterSave.getUniqueId(); + + ArtifactDefinition artifactInfo = addArtifactToService(userId, serviceId, "install_apache"); + + Either service = serviceOperation.getService(serviceId); + assertTrue(service.isLeft()); + + Map artifacts = service.left().value().getArtifacts(); + assertEquals(1, artifacts.size()); + + for (Map.Entry entry : artifacts.entrySet()) { + String artifactId = entry.getValue().getUniqueId(); + String description = entry.getValue().getDescription(); + assertEquals("hdkfhskdfgh", description); + + artifactInfo.setDescription("jghlsk new desfnjdh"); + + artifactOperation.updateArifactOnResource(artifactInfo, serviceId, artifactId, NodeTypeEnum.Service, false); + } + + service = serviceOperation.getService(serviceId); + assertTrue(service.isLeft()); + + artifacts = service.left().value().getArtifacts(); + for (Map.Entry entry : artifacts.entrySet()) { + String artifactId = entry.getValue().getUniqueId(); + String description = entry.getValue().getDescription(); + assertEquals("jghlsk new desfnjdh", description); + + artifactOperation.removeArifactFromResource(serviceId, artifactId, NodeTypeEnum.Service, true, false); + } + service = serviceOperation.getService(serviceId); + assertTrue(service.isLeft()); + + artifacts = service.left().value().getArtifacts(); + assertEquals(0, artifacts.size()); + + Either serviceDelete = serviceOperation.deleteService(serviceId); + + Either, TitanOperationStatus> byCriteria = titanDao.getByCriteria(NodeTypeEnum.ArtifactRef, + null, ArtifactData.class); + assertTrue(byCriteria.isRight()); + assertEquals(TitanOperationStatus.NOT_FOUND, byCriteria.right().value()); + + serviceOperation.deleteService(serviceAfterSave.getUniqueId()); + + } + + private ArtifactDefinition addArtifactToService(String userId, String serviceId, String artifactName) { + ArtifactDefinition artifactInfo = new ArtifactDefinition(); + + artifactInfo.setArtifactName(artifactName + ".sh"); + artifactInfo.setArtifactType("SHELL"); + artifactInfo.setDescription("hdkfhskdfgh"); + artifactInfo.setPayloadData("UEsDBAoAAAAIAAeLb0bDQz"); + + artifactInfo.setUserIdCreator(userId); + String fullName = "Jim H"; + artifactInfo.setUpdaterFullName(fullName); + long time = System.currentTimeMillis(); + artifactInfo.setCreatorFullName(fullName); + artifactInfo.setCreationDate(time); + artifactInfo.setLastUpdateDate(time); + + artifactInfo.setUserIdLastUpdater(userId); + artifactInfo.setArtifactLabel(artifactName); + artifactInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(serviceId, artifactInfo.getArtifactLabel())); + + Either artifact = artifactOperation + .addArifactToComponent(artifactInfo, serviceId, NodeTypeEnum.Service, true, true); + assertTrue(artifact.isLeft()); + return artifactInfo; + } + + @Test + public void testFollowed() { + String category = CATEGORY_NAME; + String serviceName = "servceTest2"; + String serviceVersion = "0.1"; + String userId = USER_ID; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug("{}", serviceAfterSave); + String serviceId = serviceAfterSave.getUniqueId(); + + Set lifecycleStates = new HashSet(); + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + Set lastStateStates = new HashSet(); + lastStateStates.add(LifecycleStateEnum.CERTIFIED); + + Either, StorageOperationStatus> followed = serviceOperation.getFollowed(userId, lifecycleStates, + lastStateStates, false); + assertTrue(followed.isLeft()); + List list = followed.left().value(); + assertEquals(1, list.size()); + serviceOperation.deleteService(serviceId); + } + + @Test + public void testUpdateService() { + String category = CATEGORY_NAME; + String serviceName = "12"; + String serviceVersion = "0.1"; + String userId = USER_ID; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug("{}", serviceAfterSave); + String serviceId = serviceAfterSave.getUniqueId(); + serviceAfterSave.setDescription("new description"); + Either updateService = serviceOperation.updateService(serviceAfterSave, false); + assertTrue(updateService.isLeft()); + + titanDao.commit(); + + Either serviceAfterUpdate = serviceOperation.getService(serviceId, false); + assertTrue(serviceAfterUpdate.isLeft()); + + serviceOperation.deleteService(serviceId); + assertEquals("new description", serviceAfterUpdate.left().value().getDescription()); + + } + + public Service createService(String userId, String category, String serviceName, String serviceVersion, + boolean isHighestVersion) { + + Service service = buildServiceMetadata(userId, category, serviceName, serviceVersion); + + service.setHighestVersion(isHighestVersion); + + Either result = serviceOperation.createService(service, true); + + log.info(result.toString()); + assertTrue(result.isLeft()); + Service resultService = result.left().value(); + + // assertEquals("check resource unique id", + // UniqueIdBuilder.buildServiceUniqueId(serviceName, serviceVersion), + // resultService.getUniqueId()); + assertEquals("check resource state", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + resultService.getLifecycleState()); + + return resultService; + } + + // @Test + public void testCloneFullService() { + // try{ + String userId = USER_ID; + // Either deleteService = + // serviceOperation.deleteService(UniqueIdBuilder.buildServiceUniqueId("my-service", + // "1.0"), false); + // log.info("testCloneFullService - after delete service. result + // is="+deleteService); + Service origService = createService(userId, CATEGORY_NAME, "my-service", "1.0", true); + + // add artifacts + addArtifactToService(userId, origService.getUniqueId(), "install_apache"); + addArtifactToService(userId, origService.getUniqueId(), "start_apache"); + + // add resource instances + ResourceInstanceOperationTest riTest = new ResourceInstanceOperationTest(); + riTest.setOperations(titanDao, capabilityTypeOperation, requirementOperation, capabilityOperation, + resourceOperation, propertyOperation, resourceInstanceOperation); + riTest.addResourceInstancesAndRelation(origService.getUniqueId()); + + Either service2 = serviceOperation.getService(origService.getUniqueId(), + false); + assertTrue(service2.isLeft()); + origService = service2.left().value(); + + Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + String json = prettyGson.toJson(origService); + log.debug(json); + + Service fullService = origService; + + Either createService = serviceOperation.cloneService(fullService, "2.0", + false); + assertTrue(createService.isLeft()); + Either serviceAfterCreate = serviceOperation + .getServiceByNameAndVersion("my-service", "2.0", null, false); + assertTrue(serviceAfterCreate.isLeft()); + fullService = serviceAfterCreate.left().value(); + + Either getOrigService = serviceOperation + .getServiceByNameAndVersion("my-service", "1.0", null, false); + assertTrue(getOrigService.isLeft()); + origService = getOrigService.left().value(); + + // assertEquals(origService.getComponentMetadataDefinition(), + // fullService.getComponentMetadataDefinition()); + assertEquals(origService.getArtifacts().size(), fullService.getArtifacts().size()); + assertEquals(origService.getComponentInstances().size(), fullService.getComponentInstances().size()); + assertEquals(origService.getComponentInstancesRelations().size(), + fullService.getComponentInstancesRelations().size()); + + origService.setUniqueId(fullService.getUniqueId()); + origService.setVersion(fullService.getVersion()); + + assertEquals(origService.getComponentMetadataDefinition(), fullService.getComponentMetadataDefinition()); + assertEquals(origService.getCategories(), fullService.getCategories()); + + serviceOperation.deleteService(origService.getUniqueId()); + serviceOperation.deleteService(serviceAfterCreate.left().value().getUniqueId()); + + // } finally { + // titanDao.rollback(); + // Either serviceAfterCreate = + // serviceOperation.getService(UniqueIdBuilder.buildServiceUniqueId("my-service", + // "2.0"), true); + // assertTrue(serviceAfterCreate.isRight()); + // + // Either getOrigService = + // serviceOperation.getService(UniqueIdBuilder.buildServiceUniqueId("my-service", + // "1.0"), true); + // assertTrue(getOrigService.isRight()); + // titanDao.rollback(); + // } + } + + // @Test + public void testCloneServiceWithoutResourceInstances() { + // try{ + String userId = USER_ID; + // Either deleteService = + // serviceOperation.deleteService(UniqueIdBuilder.buildServiceUniqueId("my-service", + // "1.0"), false); + // log.info("testCloneServiceWithoutResourceInstances - after delete + // service. result is="+deleteService); + Service origService = createService(userId, CATEGORY_NAME, "my-service", "1.0", true); + + // add artifacts + addArtifactToService(userId, origService.getUniqueId(), "install_apache"); + addArtifactToService(userId, origService.getUniqueId(), "start_apache"); + + Either service2 = serviceOperation.getService(origService.getUniqueId(), + false); + assertTrue(service2.isLeft()); + origService = service2.left().value(); + + Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + String json = prettyGson.toJson(origService); + log.debug(json); + + Service fullService = origService; + + Either createService = serviceOperation.cloneService(fullService, "2.0", + false); + assertTrue(createService.isLeft()); + Either serviceAfterCreate = serviceOperation + .getServiceByNameAndVersion("my-service", "2.0", null, false); + assertTrue(serviceAfterCreate.isLeft()); + fullService = serviceAfterCreate.left().value(); + + Either getOrigService = serviceOperation + .getServiceByNameAndVersion("my-service", "1.0", null, false); + assertTrue(getOrigService.isLeft()); + origService = getOrigService.left().value(); + + // assertEquals(origService.getComponentMetadataDefinition(), + // fullService.getComponentMetadataDefinition()); + assertEquals(origService.getArtifacts().size(), fullService.getArtifacts().size()); + assertEquals(origService.getComponentInstances(), fullService.getComponentInstances()); + assertEquals(origService.getComponentInstancesRelations(), fullService.getComponentInstancesRelations()); + + origService.setUniqueId(fullService.getUniqueId()); + origService.setVersion(fullService.getVersion()); + + assertEquals(origService.getComponentMetadataDefinition(), fullService.getComponentMetadataDefinition()); + assertEquals(origService.getCategories(), fullService.getCategories()); + + serviceOperation.deleteService(getOrigService.left().value().getUniqueId()); + serviceOperation.deleteService(serviceAfterCreate.left().value().getUniqueId()); + + // } finally { + // titanDao.rollback(); + // } + } + + // @Test + public void testCloneServiceWithoutArtifacts() { + // try{ + + String userId = USER_ID; + + Service origService = createService(userId, CATEGORY_NAME, "my-service", "1.0", true); + + // add resource instances + ResourceInstanceOperationTest riTest = new ResourceInstanceOperationTest(); + riTest.setOperations(titanDao, capabilityTypeOperation, requirementOperation, capabilityOperation, + resourceOperation, propertyOperation, resourceInstanceOperation); + riTest.addResourceInstancesAndRelation(origService.getUniqueId()); + + Either service2 = serviceOperation.getService(origService.getUniqueId(), + false); + assertTrue(service2.isLeft()); + origService = service2.left().value(); + + Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + String json = prettyGson.toJson(origService); + log.debug(json); + + Service fullService = origService; + + Either createService = serviceOperation.cloneService(fullService, "2.0", + false); + assertTrue(createService.isLeft()); + Either serviceAfterCreate = serviceOperation + .getServiceByNameAndVersion("my-service", "2.0", null, false); + assertTrue(serviceAfterCreate.isLeft()); + fullService = serviceAfterCreate.left().value(); + + Either getOrigService = serviceOperation + .getServiceByNameAndVersion("my-service", "1.0", null, false); + assertTrue(getOrigService.isLeft()); + origService = getOrigService.left().value(); + + assertEquals(origService.getArtifacts(), fullService.getArtifacts()); + assertEquals(origService.getComponentInstances().size(), fullService.getComponentInstances().size()); + assertEquals(origService.getComponentInstancesRelations().size(), + fullService.getComponentInstancesRelations().size()); + + origService.setUniqueId(fullService.getUniqueId()); + origService.setVersion(fullService.getVersion()); + + assertEquals(origService.getComponentMetadataDefinition(), fullService.getComponentMetadataDefinition()); + assertEquals(origService.getCategories(), fullService.getCategories()); + + serviceOperation.deleteService(serviceAfterCreate.left().value().getUniqueId()); + serviceOperation.deleteService(getOrigService.left().value().getUniqueId()); + + // } finally { + // titanDao.rollback(); + // } + } + + // @Test + public void testCloneServiceSimple() { + // try{ + String userId = USER_ID; + String serviceName = "serviceToClone"; + // + // Either deleteService = + // serviceOperation.deleteService(UniqueIdBuilder.buildServiceUniqueId(serviceName, + // "1.0")); + // log.info("testCloneServiceSimple - after delete service. result + // is="+deleteService); + + Service origService = createService(userId, CATEGORY_NAME, serviceName, "1.0", true); + + Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + String json = prettyGson.toJson(origService); + log.debug(json); + + Service fullService = origService; + + Either createService = serviceOperation.cloneService(fullService, "2.0", + false); + assertTrue(createService.isLeft()); + Either serviceAfterCreate = serviceOperation + .getServiceByNameAndVersion(serviceName, "2.0", null, false); + assertTrue(serviceAfterCreate.isLeft()); + fullService = serviceAfterCreate.left().value(); + + Either getOrigService = serviceOperation + .getServiceByNameAndVersion(serviceName, "1.0", null, false); + assertTrue(getOrigService.isLeft()); + origService = getOrigService.left().value(); + + // assertEquals(origService.getComponentMetadataDefinition(), + // fullService.getComponentMetadataDefinition()); + assertEquals(origService.getArtifacts(), fullService.getArtifacts()); + assertEquals(origService.getComponentInstances(), fullService.getComponentInstances()); + assertEquals(origService.getComponentInstancesRelations(), fullService.getComponentInstancesRelations()); + origService.setUniqueId(fullService.getUniqueId()); + origService.setVersion(fullService.getVersion()); + + assertEquals(origService.getComponentMetadataDefinition(), fullService.getComponentMetadataDefinition()); + assertEquals(origService.getCategories(), fullService.getCategories()); + + serviceOperation.deleteService(getOrigService.left().value().getUniqueId()); + serviceOperation.deleteService(serviceAfterCreate.left().value().getUniqueId()); + + // } finally { + // titanDao.rollback(); + // } + } + + private Service buildServiceMetadata(String userId, String category, String serviceName, String serviceVersion) { + + Service service = new Service(); + service.setName(serviceName); + service.setVersion(serviceVersion); + service.setDescription("description 1"); + + service.setCreatorUserId(userId); + service.setContactId("contactId@sdc.com"); + CategoryDefinition categoryDef = new CategoryDefinition(); + categoryDef.setName(category); + + List categories = new ArrayList<>(); + categories.add(categoryDef); + service.setCategories(categories); + + service.setIcon("images/my.png"); + List tags = new ArrayList(); + tags.add("TAG1"); + tags.add("TAG2"); + service.setTags(tags); + return service; + } + + private void deleteAndCreateCategory(String category) { + String[] names = category.split("/"); + OperationTestsUtil.deleteAndCreateServiceCategory(category, titanDao); + OperationTestsUtil.deleteAndCreateResourceCategory(names[0], names[1], titanDao); + + /* + * CategoryData categoryData = new CategoryData(); + * categoryData.setName(category); + * + * titanDao.deleteNode(categoryData, CategoryData.class); + * Either createNode = + * titanDao.createNode(categoryData, CategoryData.class); + * System.out.println("after creating caetgory " + createNode); + */ + + } + + private UserData deleteAndCreateUser(String userId, String firstName, String lastName, String role) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setFirstName(firstName); + userData.setLastName(lastName); + if (role != null && !role.isEmpty()) { + userData.setRole(role); + } else { + userData.setRole("ADMIN"); + } + + titanDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class); + titanDao.createNode(userData, UserData.class); + titanDao.commit(); + + return userData; + } + + @Test + public void testCatalogService() { + String userId = USER_ID; + String category = CATEGORY_NAME; + String serviceName = "MyService"; + String serviceVersion = "0.1"; + Service serviceAfterSave = createService(userId, category, serviceName, serviceVersion, true); + log.debug("{}", serviceAfterSave); + String serviceId = serviceAfterSave.getUniqueId(); + + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + Either, StorageOperationStatus> catalog = serviceOperation.getCatalogData(propertiesToMatch, + false); + assertTrue(catalog.isLeft()); + Set catalogSet = catalog.left().value(); + Set idSet = new HashSet<>(); + for (Service service : catalogSet) { + idSet.add(service.getUniqueId()); + } + assertTrue(idSet.contains(serviceId)); + serviceOperation.deleteService(serviceId); + } + + @After + public void teardown() { + clearGraph(); + } + + private void clearGraph() { + Either graphResult = titanDao.getGraph(); + TitanGraph graph = graphResult.left().value(); + + Iterable vertices = graph.query().vertices(); + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + // graph.removeVertex(vertex); + vertex.remove(); + } + + } + titanDao.commit(); + } + + @Test + public void testTesterFollowed() { + String serviceName = "Test1"; + String serviceName2 = "Test2"; + String serviceName3 = "Test3"; + String userId = USER_ID; + String testerUserId = "tt0004"; + String category = CATEGORY_NAME; + deleteAndCreateUser(testerUserId, "tester", "last", "TESTER"); + // deleteAndCreateCategory(category); + + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + Either findUser = titanDao.getNode(key, userId, UserData.class); + User adminUser = OperationTestsUtil.convertUserDataToUser(findUser.left().value()); + Either findTesterUser = titanDao.getNode(key, testerUserId, UserData.class); + User testerUser = OperationTestsUtil.convertUserDataToUser(findTesterUser.left().value()); + + // Create 3 new services + Service resultService = createService(userId, category, serviceName, "0.1", false); + log.debug("{}", resultService); + String serviceId = resultService.getUniqueId(); + Service resultService2 = createService(userId, category, serviceName2, "0.1", false); + log.debug("{}", resultService2); + String serviceId2 = resultService2.getUniqueId(); + Service resultService3 = createService(userId, category, serviceName3, "0.1", false); + log.debug("{}", resultService3); + String serviceId3 = resultService3.getUniqueId(); + + // update 1 service to READY_FOR_CERTIFICATION + Either certReqResponse = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultService, adminUser, adminUser, false); + Service RFCService = (Service) certReqResponse.left().value(); + assertEquals(RFCService.getLifecycleState(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + + // update 1 service to CERTIFICATION_IN_PROGRESS + Either startCertificationResponse = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultService2, testerUser, adminUser, false); + Service IPService = (Service) startCertificationResponse.left().value(); + assertEquals(IPService.getLifecycleState(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + Set lifecycleStates = new HashSet(); + lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + Either, StorageOperationStatus> services = serviceOperation.getTesterFollowed(testerUserId, + lifecycleStates, false); + + assertTrue(services.isLeft()); + List result = services.left().value(); + + List ids = new ArrayList<>(); + for (Service service : result) { + ids.add(service.getUniqueId()); + } + assertTrue(ids.contains(serviceId)); + assertTrue(ids.contains(serviceId2)); + assertFalse(ids.contains(serviceId3)); + serviceOperation.deleteService(serviceId); + serviceOperation.deleteService(serviceId2); + serviceOperation.deleteService(serviceId3); + + } + + @Test + public void testOpsFollowed() { + String serviceName = "Test1"; + String serviceName2 = "Test2"; + String serviceName3 = "Test3"; + String serviceName4 = "Test4"; + String userId = USER_ID; + String category = CATEGORY_NAME; + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + Either findUser = titanDao.getNode(key, userId, UserData.class); + User adminUser = OperationTestsUtil.convertUserDataToUser(findUser.left().value()); + + // Create 4 new services + Service resultService = createService(userId, category, serviceName, "0.1", false); + log.debug("{}", resultService); + String serviceId = resultService.getUniqueId(); + Service resultService2 = createService(userId, category, serviceName2, "0.1", false); + log.debug("{}", resultService2); + String serviceId2 = resultService2.getUniqueId(); + Service resultService3 = createService(userId, category, serviceName3, "0.1", false); + log.debug("{}", resultService3); + String serviceId3 = resultService3.getUniqueId(); + Service resultService4 = createService(userId, category, serviceName4, "0.1", false); + log.debug("{}", resultService3); + String serviceId4 = resultService4.getUniqueId(); + + // update 1 service to CERTIFIED dist status DISTRIBUTED + Either reqCertificationResult = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultService, adminUser, adminUser, false); + Either startCertificationResult = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultService, adminUser, adminUser, false); + Service actualService = (Service) startCertificationResult.left().value(); + + Either certResponse = lifecycleOperation + .certifyComponent(NodeTypeEnum.Service, resultService, adminUser, adminUser, false); + Service certifiedService = (Service) certResponse.left().value(); + serviceOperation.updateDestributionStatus(resultService, adminUser, DistributionStatusEnum.DISTRIBUTED); + + // update 1 service to CERTIFIED dist status DISTRIBUTION_APPROVED + Either reqCertificationResult2 = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultService2, adminUser, adminUser, false); + Either startCertificationResult2 = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultService2, adminUser, adminUser, false); + Service actualService2 = (Service) startCertificationResult2.left().value(); + + Either certResponse2 = lifecycleOperation + .certifyComponent(NodeTypeEnum.Service, resultService2, adminUser, adminUser, false); + Service certifiedService2 = (Service) certResponse2.left().value(); + serviceOperation.updateDestributionStatus(resultService2, adminUser, + DistributionStatusEnum.DISTRIBUTION_APPROVED); + + // update 1 service to CERTIFIED dist status DISTRIBUTION_REJECTED + Either reqCertificationResult3 = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultService3, adminUser, adminUser, false); + Either startCertificationResult3 = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultService3, adminUser, adminUser, false); + Service actualService3 = (Service) startCertificationResult3.left().value(); + + Either certResponse3 = lifecycleOperation + .certifyComponent(NodeTypeEnum.Service, actualService3, adminUser, adminUser, false); + Service certifiedService3 = (Service) certResponse3.left().value(); + serviceOperation.updateDestributionStatus(certifiedService3, adminUser, + DistributionStatusEnum.DISTRIBUTION_REJECTED); + + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + Set distStatus = new HashSet(); + distStatus.add(DistributionStatusEnum.DISTRIBUTION_APPROVED); + distStatus.add(DistributionStatusEnum.DISTRIBUTED); + + Either, StorageOperationStatus> services = serviceOperation + .getCertifiedServicesWithDistStatus(propertiesToMatch, distStatus, false); + + assertTrue(services.isLeft()); + Set result = services.left().value(); + + List ids = new ArrayList<>(); + for (Service service : result) { + ids.add(service.getUniqueId()); + } + assertTrue(ids.contains(certifiedService.getUniqueId())); + assertTrue(ids.contains(certifiedService2.getUniqueId())); + assertFalse(ids.contains(certifiedService3.getUniqueId())); + assertFalse(ids.contains(resultService4.getUniqueId())); + serviceOperation.deleteService(serviceId); + serviceOperation.deleteService(serviceId2); + serviceOperation.deleteService(serviceId3); + serviceOperation.deleteService(serviceId4); + } + + @Test + public void testGovernorFollowed() { + String serviceName = "Test1"; + String serviceName2 = "Test2"; + String serviceName3 = "Test3"; + String userId = USER_ID; + String category = CATEGORY_NAME; + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + Either findUser = titanDao.getNode(key, userId, UserData.class); + User adminUser = OperationTestsUtil.convertUserDataToUser(findUser.left().value()); + + // Create 3 new services + Service resultService = createService(userId, category, serviceName, "0.1", false); + log.debug("{}", resultService); + String serviceId = resultService.getUniqueId(); + Service resultService2 = createService(userId, category, serviceName2, "0.1", false); + log.debug("{}", resultService2); + String serviceId2 = resultService2.getUniqueId(); + Service resultService3 = createService(userId, category, serviceName3, "0.1", false); + log.debug("{}", resultService3); + String serviceId3 = resultService3.getUniqueId(); + + // update 1 service to CERTIFIED + DISTRIBUTED + Either reqCertificationResult = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultService, adminUser, adminUser, false); + Either startCertificationResult = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultService, adminUser, adminUser, false); + Service actualService = (Service) startCertificationResult.left().value(); + + Either certResponse = lifecycleOperation + .certifyComponent(NodeTypeEnum.Service, actualService, adminUser, adminUser, false); + Service certifiedService = (Service) certResponse.left().value(); + serviceOperation.updateDestributionStatus(certifiedService, adminUser, DistributionStatusEnum.DISTRIBUTED); + + // update 1 service to CERTIFIED dist status + DISTRIBUTION_REJECTED + Either reqCertificationResult2 = lifecycleOperation + .requestCertificationComponent(NodeTypeEnum.Service, resultService2, adminUser, adminUser, false); + Either startCertificationResult2 = lifecycleOperation + .startComponentCertification(NodeTypeEnum.Service, resultService2, adminUser, adminUser, false); + Service actualService2 = (Service) startCertificationResult2.left().value(); + + Either certResponse2 = lifecycleOperation + .certifyComponent(NodeTypeEnum.Service, actualService2, adminUser, adminUser, false); + Service certifiedService2 = (Service) certResponse2.left().value(); + serviceOperation.updateDestributionStatus(certifiedService2, adminUser, DistributionStatusEnum.DISTRIBUTED); + + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + Either, StorageOperationStatus> services = serviceOperation + .getCertifiedServicesWithDistStatus(propertiesToMatch, null, false); + + assertTrue(services.isLeft()); + Set result = services.left().value(); + + List ids = new ArrayList<>(); + for (Service service : result) { + ids.add(service.getUniqueId()); + } + assertTrue(ids.contains(certifiedService.getUniqueId())); + assertTrue(ids.contains(certifiedService2.getUniqueId())); + assertFalse(ids.contains(serviceId3)); + serviceOperation.deleteService(serviceId); + serviceOperation.deleteService(serviceId2); + serviceOperation.deleteService(serviceId3); + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperationTest.java new file mode 100644 index 0000000000..f77e477ed7 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperationTest.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.be.model.operations.impl; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.structure.Property; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +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.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ModelTestBase; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.common.api.UserRoleEnum; + +import fj.data.Either; + +public class UserAdminOperationTest extends ModelTestBase { + @InjectMocks + private static final UserAdminOperation userAdminOperation = new UserAdminOperation(); + private static final TitanGenericDao titanGenericDao = mock(TitanGenericDao.class); + + private static final String ADMIN = "admin"; + + @BeforeClass + public static void setup() { + ModelTestBase.init(); + } + + @Before + public void initMocks() { + MockitoAnnotations.initMocks(this); + Mockito.reset(titanGenericDao); + mockTitanUpdate(); + mockTitanDelete(); + + } + + @Test + public void testDeActivateUserDataSuccess() { + UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true); + + Either eitherUser = userAdminOperation + .deActivateUser(userAdminOperation.convertToUser(userData)); + + verify(titanGenericDao, times(1)).updateNode(Mockito.eq(userData), Mockito.eq(UserData.class)); + verify(titanGenericDao, times(0)).deleteNode(Mockito.any(UserData.class), Mockito.eq(UserData.class)); + assertTrue(eitherUser.isLeft()); + User user = eitherUser.left().value(); + assertTrue(user.getStatus() == UserStatusEnum.INACTIVE); + + } + + /* + * @Test public void testDeActivateUserDataFail(){ UserData userData = + * mockTitanGet(ADMIN, UserRoleEnum.ADMIN, false); + * + * Either eitherUser = + * userAdminOperation.deActivateUser(userAdminOperation.convertToUser( + * userData)); + * + * verify(titanGenericDao, times(0)).updateNode(Mockito.any(UserData.class), + * Mockito.eq(UserData.class)); verify(titanGenericDao, + * times(0)).deleteNode(Mockito.any(UserData.class), + * Mockito.eq(UserData.class)); assertTrue(eitherUser.isRight()); + * assertTrue(eitherUser.right().value() == + * StorageOperationStatus.USER_INACTIVE); + * + * } + */ + + @Test + public void testDeleteUserWithoutResources() { + UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true); + + List edgesList = new ArrayList(); + + Either, TitanOperationStatus> eitherResult = Either.left(edgesList); + when(titanGenericDao.getEdgesForNode(userData, Direction.BOTH)).thenReturn(eitherResult); + + Either eitherUser = userAdminOperation.deleteUserData(ADMIN); + verify(titanGenericDao, times(0)).updateNode(Mockito.any(UserData.class), Mockito.eq(UserData.class)); + verify(titanGenericDao, times(1)).deleteNode(userData, UserData.class); + assertTrue(eitherUser.isLeft()); + + } + + @Test + public void testDeleteUserWithResources() { + UserData userData = mockTitanGet(ADMIN, UserRoleEnum.ADMIN, true); + + List edgesList = new ArrayList(); + edgesList.add(getEmptyEdgeImpl()); + + Either, TitanOperationStatus> eitherResult = Either.left(edgesList); + when(titanGenericDao.getEdgesForNode(userData, Direction.BOTH)).thenReturn(eitherResult); + + Either eitherUser = userAdminOperation.deleteUserData(ADMIN); + verify(titanGenericDao, times(0)).updateNode(Mockito.any(UserData.class), Mockito.eq(UserData.class)); + verify(titanGenericDao, times(0)).deleteNode(Mockito.any(UserData.class), Mockito.eq(UserData.class)); + assertTrue(eitherUser.isRight()); + assertTrue(eitherUser.right().value() == ActionStatus.USER_HAS_ACTIVE_ELEMENTS); + + } + + private Edge getEmptyEdgeImpl() { + return new Edge() { + + @Override + public Object id() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String label() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Graph graph() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Property property(String key, V value) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void remove() { + // TODO Auto-generated method stub + + } + + @Override + public Iterator vertices(Direction direction) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterator> properties(String... propertyKeys) { + // TODO Auto-generated method stub + return null; + } + + }; + } + + private UserData mockTitanGet(String userId, UserRoleEnum role, boolean isActive) { + UserData userData = buildUserData(userId, role, isActive); + Either eitherUserData = Either.left(userData); + when(titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), userId, UserData.class)) + .thenReturn(eitherUserData); + return userData; + } + + private static void mockTitanUpdate() { + doAnswer(new Answer>() { + public Either answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + UserData retValue = (UserData) args[0]; + Either result = Either.left(retValue); + return result; + } + + }).when(titanGenericDao).updateNode(Mockito.any(UserData.class), Mockito.eq(UserData.class)); + } + + private static void mockTitanDelete() { + doAnswer(new Answer>() { + public Either answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + UserData retValue = (UserData) args[0]; + Either result = Either.left(retValue); + return result; + } + + }).when(titanGenericDao).deleteNode(Mockito.any(UserData.class), Mockito.eq(UserData.class)); + } + + private static UserData buildUserData(String userId, UserRoleEnum role, boolean isActive) { + UserData userData = new UserData(); + userData.setUserId(userId); + userData.setRole(role.getName()); + userData.setStatus(isActive ? UserStatusEnum.ACTIVE.name() : UserStatusEnum.INACTIVE.name()); + return userData; + + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/DataTypeValidatorTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/DataTypeValidatorTest.java new file mode 100644 index 0000000000..2b9c296eb5 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/DataTypeValidatorTest.java @@ -0,0 +1,1004 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.operations.impl.util; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Test; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.ListConverter; +import org.openecomp.sdc.be.model.tosca.converters.MapConverter; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.ListValidator; +import org.openecomp.sdc.be.model.tosca.validators.MapValidator; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; + +import fj.data.Either; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DataTypeValidatorTest { + private static Logger log = LoggerFactory.getLogger(DataTypeValidatorTest.class.getName()); + private static Gson gson = new Gson(); + + DataTypeValidatorConverter dataTypeValidator = DataTypeValidatorConverter.getInstance(); + + @Test + public void testDerivedFromPrimitiveEmptyValue() { + + Map allDataTypes = new HashMap(); + allDataTypes.put("integer", getPrimitiveDataType("integer")); + + DataTypeDefinition fromIntegerType = buildDerivedFromIntegerType(); + ImmutablePair validate = dataTypeValidator.validateAndUpdate("", fromIntegerType, + allDataTypes); + + assertTrue("check result is valid", validate.right.booleanValue()); + assertEquals("check value is the same as sent", null, validate.left); + + validate = dataTypeValidator.validateAndUpdate(null, fromIntegerType, allDataTypes); + + assertTrue("check result is valid", validate.right.booleanValue()); + assertEquals("check value is the same as sent", null, validate.left); + + validate = dataTypeValidator.validateAndUpdate("88", fromIntegerType, allDataTypes); + + assertTrue("check result is valid", validate.right.booleanValue()); + assertEquals("check value is the same as sent", "88", validate.left.toString()); + + } + + @Test + public void testCompositeWithParameterDerivedFromPrimitiveEmptyValue() { + + DataTypeDefinition derivedFromIntegerType = buildDerivedFromIntegerType(); + Map allDataTypes = new HashMap(); + allDataTypes.put("myinteger", derivedFromIntegerType); + + DataTypeDefinition personDataType = buildPersonDataType(); + + Person person = new Person("my address", 32); + String json = gson.toJson(person); + log.debug(json); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, personDataType, + allDataTypes); + assertTrue("check valid value", validate.right.booleanValue()); + + person = new Person("my address", 32); + json = gson.toJson(person); + json = json.replace("32", "32a"); + log.debug(json); + + validate = dataTypeValidator.validateAndUpdate(json, personDataType, allDataTypes); + assertFalse("check valid value", validate.right.booleanValue()); + + } + + @Test + public void testCompositeWithEmptyListValue() { + + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + String[] strArr = {}; + List strList = Arrays.asList(strArr); + + // Check empty list + Credential credential = new Credential("protcol
>", 5, "token_type", "token", null, "user", true, strList); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + log.debug(json); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertTrue("check valid value", validate.right.booleanValue()); + + Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class); + assertEquals("check empty list", 0, credentialRes.getMylist().size()); + + log.debug("Result is = {}", validate.left.toString()); + + } + + @Test + public void testCompositeWithListNullValue() { + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + // Check list is NULL + Credential credential = new Credential("protcol
>", 5, "token_type", "token", null, "user", true, null); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertTrue("check valid value", validate.right.booleanValue()); + + Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class); + assertNull("check list is null", credentialRes.getMylist()); + log.debug("Result is = {}", validate.left.toString()); + + } + + @Test + public void testCompositeWithUserNullValue() { + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + // Check user is null + Credential credential = new Credential("protcol
>", 5, "token_type", "token", null, null, true, null); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertTrue("check valid value", validate.right.booleanValue()); + + Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class); + assertNull("check list is null", credentialRes.getUser()); + log.debug("Result is = {}", validate.left.toString()); + } + + @Test + public void testCompositeWithEmptyUserValue() { + + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + // Check user is empty + Credential credential = new Credential("protcol
>", 5, "token_type", "token", null, "", true, null); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + log.debug(json); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertTrue("check valid value", validate.right.booleanValue()); + + Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class); + assertNotNull("check list is not null", credentialRes.getUser()); + assertEquals("check user is empty", "", credentialRes.getUser()); + log.debug("Result is = {}", validate.left.toString()); + + } + + @Test + public void testCompositeWithSumNullValue() { + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + // Check user is null + Credential credential = new Credential("protcol
>", null, "token_type", "token", null, null, true, null); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertTrue("check valid value", validate.right.booleanValue()); + + Credential credentialRes = gson.fromJson(validate.left.toString(), Credential.class); + assertNull("check list is null", credentialRes.getSum()); + log.debug("Result is = {}", validate.left.toString()); + } + + @Test + public void testInvalidJson() { + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + // Check user is null + Credential credential = new Credential("protcol
>", null, "token_type", "token", null, null, true, null); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + + json += "fdfd"; + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertFalse("check valid value", validate.right.booleanValue()); + + } + + @Test + public void testInvalidInnerValue() { + + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + // Check user is null + Credential credential = new Credential("protcol
>", null, "token_type", "token", null, null, true, null); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + + json = json.replace("55", "a55b"); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertFalse("check valid value", validate.right.booleanValue()); + + } + + @Test + public void testInvalidInnerJson() { + + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + // Check user is null + Credential credential = new Credential("protcol
>", null, "token_type", "token", null, null, true, null); + City mycity = new City("", null); + + credential.setMycity(mycity); + + String json = gson.toJson(credential); + + json = json.replace("{\"address\":\"\"}", "scalar"); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertFalse("check valid value", validate.right.booleanValue()); + + } + + @Test + public void testInvalidPropertyJson() { + + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + // Check user is null + Credential credential = new Credential("protcol
>", null, "token_type", "token", null, null, true, null); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + + json = json.replace("55", "a55b"); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertFalse("check valid value", validate.right.booleanValue()); + + } + + @Test + public void testCompositeDataTypeWithInternalComposite() { + + DataTypeDefinition dataTypeDefinition = buildCredentialDataType(); + + String[] strArr = { "aaa", "bbb", "c
dcc" }; + List strList = Arrays.asList(strArr); + + Credential credential = new Credential("protcol
>", 5, "token_type", "token", null, "user", true, strList); + City mycity = new City("myadd
<
", 55); + credential.setMycity(mycity); + + String json = gson.toJson(credential); + + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + ImmutablePair validate = dataTypeValidator.validateAndUpdate(json, dataTypeDefinition, + allDataTypes); + assertTrue("check valid value", validate.right.booleanValue()); + + log.debug("Result is = {}", validate.left.toString()); + + } + + @Test + public void testMapValidator() { + + MapValidator validator = new MapValidator(); + Gson gson = new Gson(); + // Happy Scenarios + // 1 - Map check OK + Map map_1 = new HashMap<>(); + map_1.put("key1", 2); + map_1.put("key2", 3); + String value = gson.toJson(map_1); + String innerType = "integer"; + assertTrue("Test Map validation with inner integer type", validator.isValid(value, innerType, null)); + + // 2 - Map check OK + Map map_2 = new HashMap<>(); + map_2.put("key1", true); + map_2.put("key2", false); + value = gson.toJson(map_2); + innerType = "boolean"; + assertTrue("Test Map validation with inner boolean type", validator.isValid(value, innerType, null)); + + // 3 - give integer with quotes + innerType = "integer"; + value = "{\"key1\":\"5\",\"key2\":\"7\"}"; + assertTrue("Test Map validation with inner integer type, but qouted values", + validator.isValid(value, innerType, null)); + + // 4 - empty default value + innerType = "float"; + value = ""; + assertTrue("Test Map validation with inner float type", validator.isValid(value, innerType, null)); + + // Faulty Scenarios + // 5 - mismatch in data type + value = gson.toJson(map_1); + innerType = "boolean"; + assertFalse("Test Map faulty validation with inner boolean type", validator.isValid(value, innerType, null)); + // 6 - mismatch in data type + value = gson.toJson(map_2); + innerType = "integer"; + assertFalse("Test Map faulty validation with inner integer type", validator.isValid(value, innerType, null)); + + } + + @Test + public void testMapConverter() { + + MapConverter converter = new MapConverter(); + Gson gson = new Gson(); + // Happy Scenarios + Map map_1 = new HashMap<>(); + Map resMap_1 = new HashMap<>(); + + // 1 - check Spaces eliminated + html square brackets eliminated + map_1.put("key1", "test"); + map_1.put("key2", " test"); + resMap_1.put("key1", "test"); + resMap_1.put("key2", " test"); + String value = gson.toJson(map_1); + String expectedVal = gson.toJson(resMap_1); + String innerType = "string"; + assertEquals("Test Map validation with inner string type", expectedVal, + converter.convert(value, innerType, null)); + + // 2 - float converter + innerType = "float"; + value = "{\"key1\":0.4545,\"key2\":0.2f}"; + expectedVal = "{\"key1\":0.4545,\"key2\":0.2}"; + assertEquals("Test Map validation with inner float type", expectedVal, + converter.convert(value, innerType, null)); + + // 3 - check default empty value converter + innerType = "float"; + value = ""; + expectedVal = ""; + assertEquals("Test Map validation with inner float type", expectedVal, + converter.convert(value, innerType, null)); + + // 4 - invalid json + // 3 - check default empty value converter + innerType = "float"; + value = "{1345234556@#("; + expectedVal = null; + assertEquals("Test Map validation with inner float type", expectedVal, + converter.convert(value, innerType, null)); + + } + + @Test + public void testCompositeDataTypeWithMapComposite() { + + DataTypeDefinition fileDataTypeDefinition = buildFileDataType(); + Map allDataTypes = new HashMap(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + + MyFile myFile = new MyFile(); + myFile.setAge(88); + Map attributes = new HashMap<>(); + attributes.put("key1", new City("address1
", 11)); + attributes.put("key2", new City("address2
", 22)); + myFile.setAttributes(attributes); + + String str = gson.toJson(myFile); + log.debug(str); + + ImmutablePair convert = dataTypeValidator.validateAndUpdate(str, fileDataTypeDefinition, + allDataTypes); + + assertTrue("check map converter succeed", convert.right); + + JsonElement convertedValue = convert.left; + + log.debug("{}", convertedValue); + MyFile fromJson = gson.fromJson(convertedValue, MyFile.class); + + assertEquals("check age", 88, fromJson.getAge().intValue()); + assertEquals("check address 1", "address1", fromJson.getAttributes().get("key1").getAddress()); + assertEquals("check address 2", "address2", fromJson.getAttributes().get("key2").getAddress()); + + } + + @Test + public void testMapConverterWithComplexInnerType() { + + Map allDataTypes = new HashMap(); + DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + allDataTypes.put("credential", credentialDataTypeDefinition); + + Gson gson = new Gson(); + // Happy Scenarios + Map map_1 = new HashMap<>(); + + // 1 - check Spaces eliminated + html square brackets eliminated + + String[] strArr = { "aaa", "bbb", "c
dcc" }; + List strList = Arrays.asList(strArr); + Credential credential1 = new Credential("protocol;:,.\"
>", 5, "token_type", "token", null, "user", true, + strList); + City mycity1 = new City("myadd
<
", 55); + credential1.setMycity(mycity1); + + Credential credential2 = new Credential("protocol;:,.\"
>", 5, "token_type", "token", null, "user", true, + strList); + City mycity2 = new City("myadd
<
", 66); + credential2.setMycity(mycity2); + + map_1.put("key1", credential1); + map_1.put("key2", credential2); + + String str = gson.toJson(map_1); + log.debug(str); + + MapConverter mapConverter = new MapConverter(); + Either convert = mapConverter.convertWithErrorResult(str, "credential", allDataTypes); + + assertTrue("check map converter succeed", convert.isLeft()); + + String convertedValue = convert.left().value(); + + Type type = new TypeToken>() { + }.getType(); + + Map fromJson = gson.fromJson(convertedValue, type); + + Credential actualCredential1 = fromJson.get("key1"); + assertEquals("check sum", 5, actualCredential1.getSum().intValue()); + assertEquals("check protocol", "protocol;:,.\">", actualCredential1.getProtocol()); + String[] convertedStrArr = { "aaa", "bbb", "cdcc" }; + List convertedStrList = Arrays.asList(convertedStrArr); + assertEquals("check list", convertedStrList, actualCredential1.getMylist()); + + assertEquals("check city address", "myadd<", actualCredential1.getMycity().getAddress()); + assertEquals("check city address", 55, actualCredential1.getMycity().getAge().intValue()); + + Credential actualCredential2 = fromJson.get("key2"); + assertEquals("check city address", 66, actualCredential2.getMycity().getAge().intValue()); + + } + + @Test + public void testListConverterWithComplexInnerType() { + + Map allDataTypes = new HashMap(); + DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + allDataTypes.put("credential", credentialDataTypeDefinition); + + Gson gson = new Gson(); + + List list = buildListOf2CredentialObjects(); + + String str = gson.toJson(list); + log.debug(str); + + ListConverter listConverter = new ListConverter(); + + Either convert = listConverter.convertWithErrorResult(str, "credential", allDataTypes); + + assertTrue("check map converter succeed", convert.isLeft()); + + String convertedValue = convert.left().value(); + + validateListOfCredential(gson, convertedValue); + + list.add(null); + + str = gson.toJson(list); + log.debug(str); + + convert = listConverter.convertWithErrorResult(str, "credential", allDataTypes); + + assertTrue("check map converter succeed", convert.isLeft()); + + validateListOfCredential(gson, convertedValue); + } + + @Test + public void testListValidatorWithComplexInnerType() { + + Map allDataTypes = new HashMap(); + DataTypeDefinition credentialDataTypeDefinition = buildCredentialDataType(); + DataTypeDefinition cityDataType = buildCityDataType(); + allDataTypes.put("city", cityDataType); + allDataTypes.put("credential", credentialDataTypeDefinition); + + Gson gson = new Gson(); + // Happy Scenarios + List list = buildListOf2CredentialObjects(); + + String str = gson.toJson(list); + log.debug(str); + + ListValidator listValidator = new ListValidator(); + + boolean isValid = listValidator.isValid(str, "credential", allDataTypes); + + assertTrue("check valid value", isValid); + + String badStr = str.replace("protocol", "protocol1"); + + isValid = listValidator.isValid(badStr, "credential", allDataTypes); + + assertFalse("check valid value", isValid); + + badStr = str.replace("55", "\"aa\""); + + isValid = listValidator.isValid(badStr, "credential", allDataTypes); + + assertFalse("check valid value", isValid); + + } + + private List buildListOf2CredentialObjects() { + List list = new ArrayList<>(); + + String[] strArr = { "aaa", "bbb", "c
dcc" }; + List strList = Arrays.asList(strArr); + Credential credential1 = new Credential("protocol.,\":;
>", 5, "token_type", "token", null, "user", true, + strList); + City mycity1 = new City("myadd
<
", 55); + credential1.setMycity(mycity1); + + Credential credential2 = new Credential("protocol.,\":;
>", 5, "token_type", "token", null, "user", true, + strList); + City mycity2 = new City("myadd
<
", 66); + credential2.setMycity(mycity2); + + list.add(credential1); + list.add(credential2); + return list; + } + + private void validateListOfCredential(Gson gson, String convertedValue) { + + log.debug(convertedValue); + Type type = new TypeToken>() { + }.getType(); + + List fromJson = gson.fromJson(convertedValue, type); + + assertEquals("check list size", 2, fromJson.size()); + + // Credential actualCredential1 = gson.fromJson(list.get(0).toString(), + // Credential.class); + Credential actualCredential1 = fromJson.get(0); + assertEquals("check sum", 5, actualCredential1.getSum().intValue()); + assertEquals("check protocol", "protocol.,\":;>", actualCredential1.getProtocol()); + String[] convertedStrArr = { "aaa", "bbb", "cdcc" }; + List convertedStrList = Arrays.asList(convertedStrArr); + assertEquals("check list", convertedStrList, actualCredential1.getMylist()); + + assertEquals("check city address", "myadd<", actualCredential1.getMycity().getAddress()); + assertEquals("check city address", 55, actualCredential1.getMycity().getAge().intValue()); + + // Credential actualCredential2 = gson.fromJson(list.get(1).toString(), + // Credential.class); + Credential actualCredential2 = fromJson.get(1); + assertEquals("check city address", 66, actualCredential2.getMycity().getAge().intValue()); + } + + private DataTypeDefinition buildCredentialDataType() { + DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(); + dataTypeDefinition.setName("datatype.1"); + List properties = new ArrayList<>(); + PropertyDefinition propertyDefinition1 = new PropertyDefinition(); + propertyDefinition1.setName("sum"); + propertyDefinition1.setType(ToscaPropertyType.INTEGER.getType()); + PropertyDefinition propertyDefinition2 = new PropertyDefinition(); + propertyDefinition2.setName("protocol"); + propertyDefinition2.setType(ToscaPropertyType.STRING.getType()); + PropertyDefinition propertyDefinition3 = new PropertyDefinition(); + propertyDefinition3.setName("token_type"); + propertyDefinition3.setType(ToscaPropertyType.STRING.getType()); + PropertyDefinition propertyDefinition4 = new PropertyDefinition(); + propertyDefinition4.setName("token"); + propertyDefinition4.setType(ToscaPropertyType.STRING.getType()); + PropertyDefinition propertyDefinition5 = new PropertyDefinition(); + propertyDefinition5.setName("keys"); + propertyDefinition5.setType(ToscaPropertyType.MAP.getType()); + PropertyDefinition propertyDefinition6 = new PropertyDefinition(); + propertyDefinition6.setName("mylist"); + propertyDefinition6.setType(ToscaPropertyType.LIST.getType()); + SchemaDefinition entrySchema = new SchemaDefinition(); + PropertyDataDefinition property = new PropertyDataDefinition(); + property.setType("string"); + entrySchema.setProperty(property); + propertyDefinition6.setSchema(entrySchema); + PropertyDefinition propertyDefinition7 = new PropertyDefinition(); + propertyDefinition7.setName("user"); + propertyDefinition7.setType(ToscaPropertyType.STRING.getType()); + PropertyDefinition propertyDefinition8 = new PropertyDefinition(); + propertyDefinition8.setName("isMandatory"); + propertyDefinition8.setType(ToscaPropertyType.BOOLEAN.getType()); + + PropertyDefinition propertyDefinition9 = new PropertyDefinition(); + propertyDefinition9.setName("mycity"); + propertyDefinition9.setType("city"); + + properties.add(propertyDefinition1); + properties.add(propertyDefinition2); + properties.add(propertyDefinition3); + properties.add(propertyDefinition4); + properties.add(propertyDefinition5); + properties.add(propertyDefinition6); + properties.add(propertyDefinition7); + properties.add(propertyDefinition8); + properties.add(propertyDefinition9); + + dataTypeDefinition.setProperties(properties); + return dataTypeDefinition; + } + + private static DataTypeDefinition buildCityDataType() { + DataTypeDefinition cityDataType = new DataTypeDefinition(); + cityDataType.setName("city"); + List cityProperties = new ArrayList<>(); + PropertyDefinition cityPropertyDefinition1 = new PropertyDefinition(); + cityPropertyDefinition1.setName("age"); + cityPropertyDefinition1.setType(ToscaPropertyType.INTEGER.getType()); + PropertyDefinition cityPropertyDefinition2 = new PropertyDefinition(); + cityPropertyDefinition2.setName("address"); + cityPropertyDefinition2.setType(ToscaPropertyType.STRING.getType()); + + cityProperties.add(cityPropertyDefinition1); + cityProperties.add(cityPropertyDefinition2); + + cityDataType.setProperties(cityProperties); + return cityDataType; + } + + private static DataTypeDefinition buildPersonDataType() { + DataTypeDefinition personDataType = new DataTypeDefinition(); + personDataType.setName("person"); + List personProperties = new ArrayList<>(); + PropertyDefinition personPropertyDefinition1 = new PropertyDefinition(); + personPropertyDefinition1.setName("age"); + personPropertyDefinition1.setType("myinteger"); + PropertyDefinition personPropertyDefinition2 = new PropertyDefinition(); + personPropertyDefinition2.setName("address"); + personPropertyDefinition2.setType(ToscaPropertyType.STRING.getType()); + + personProperties.add(personPropertyDefinition1); + personProperties.add(personPropertyDefinition2); + + personDataType.setProperties(personProperties); + return personDataType; + } + + private static DataTypeDefinition buildFileDataType() { + DataTypeDefinition fileDataType = new DataTypeDefinition(); + fileDataType.setName("file"); + List fileProperties = new ArrayList<>(); + PropertyDefinition filePropertyDefinition1 = new PropertyDefinition(); + filePropertyDefinition1.setName("age"); + filePropertyDefinition1.setType("integer"); + + PropertyDefinition filePropertyDefinition2 = new PropertyDefinition(); + filePropertyDefinition2.setName("attributes"); + filePropertyDefinition2.setType(ToscaPropertyType.MAP.getType()); + + fileProperties.add(filePropertyDefinition1); + fileProperties.add(filePropertyDefinition2); + + SchemaDefinition entrySchema = new SchemaDefinition(); + PropertyDataDefinition property = new PropertyDataDefinition(); + property.setType("city"); + entrySchema.setProperty(property); + filePropertyDefinition2.setSchema(entrySchema); + + fileDataType.setProperties(fileProperties); + return fileDataType; + } + + private static DataTypeDefinition getPrimitiveDataType(String type) { + + DataTypeDefinition derivedFrom = new DataTypeDefinition(); + derivedFrom.setName(type); + + return derivedFrom; + + } + + private static DataTypeDefinition buildDerivedFromIntegerType() { + + DataTypeDefinition derivedFrom = getPrimitiveDataType("integer"); + + DataTypeDefinition myIntegerDataType = new DataTypeDefinition(); + myIntegerDataType.setDerivedFrom(derivedFrom); + + myIntegerDataType.setName("myinteger"); + + return myIntegerDataType; + } + + public static class MyFile { + + Integer age; + + Map attributes; + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + } + + public static class City { + + String address; + Integer age; + + public City(String address, Integer age) { + super(); + this.address = address; + this.age = age; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + } + + public static class Person { + + String address; + Integer age; + + public Person(String address, Integer age) { + super(); + this.address = address; + this.age = age; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + @Override + public String toString() { + return "Person [address=" + address + ", age=" + age + "]"; + } + + } + + public static class Credential { + + String protocol; + Integer sum; + String token_type; + String token; + Map keys; + String user; + Boolean isMandatory; + List mylist; + City mycity; + + public Credential(String protocol, Integer sum, String token_type, String token, Map keys, + String user, Boolean isMandatory, List mylist) { + super(); + this.protocol = protocol; + this.sum = sum; + this.token_type = token_type; + this.token = token; + this.keys = keys; + this.user = user; + this.isMandatory = isMandatory; + this.mylist = mylist; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getToken_type() { + return token_type; + } + + public void setToken_type(String token_type) { + this.token_type = token_type; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Map getKeys() { + return keys; + } + + public void setKeys(Map keys) { + this.keys = keys; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public Boolean getIsMandatory() { + return isMandatory; + } + + public void setIsMandatory(Boolean isMandatory) { + this.isMandatory = isMandatory; + } + + public Integer getSum() { + return sum; + } + + public void setSum(Integer sum) { + this.sum = sum; + } + + public List getMylist() { + return mylist; + } + + public void setMylist(List mylist) { + this.mylist = mylist; + } + + public City getMycity() { + return mycity; + } + + public void setMycity(City mycity) { + this.mycity = mycity; + } + + @Override + public String toString() { + return "Credential [protocol=" + protocol + ", token_type=" + token_type + ", token=" + token + ", keys=" + + keys + ", user=" + user + ", isMandatory=" + isMandatory + "]"; + } + + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/OperationTestsUtil.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/OperationTestsUtil.java new file mode 100644 index 0000000000..e356b49a10 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/OperationTestsUtil.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.be.model.operations.impl.util; + +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +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.User; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.ResourceCategoryData; +import org.openecomp.sdc.be.resources.data.ServiceCategoryData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.common.util.ValidationUtils; + +import fj.data.Either; + +public class OperationTestsUtil { + + public static String deleteAndCreateServiceCategory(String category, TitanGenericDao titanDao) { + CategoryData categoryData = new CategoryData(NodeTypeEnum.ServiceNewCategory); + categoryData.getCategoryDataDefinition().setName(category); + categoryData.getCategoryDataDefinition() + .setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(category)); + categoryData.getCategoryDataDefinition().setUniqueId(UniqueIdBuilder.buildCategoryUid( + ValidationUtils.normalizeCategoryName4Uniqueness(category), NodeTypeEnum.ServiceNewCategory)); + titanDao.deleteNode(categoryData, CategoryData.class); + Either createNode = titanDao.createNode(categoryData, CategoryData.class); + return (String) createNode.left().value().getUniqueId(); + } + + public static String deleteAndCreateResourceCategory(String category, String subcategory, + TitanGenericDao titanDao) { + + CategoryData categoryData = new CategoryData(NodeTypeEnum.ResourceNewCategory); + categoryData.getCategoryDataDefinition().setName(category); + categoryData.getCategoryDataDefinition() + .setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(category)); + categoryData.getCategoryDataDefinition().setUniqueId(UniqueIdBuilder.buildCategoryUid( + ValidationUtils.normalizeCategoryName4Uniqueness(category), NodeTypeEnum.ResourceNewCategory)); + + SubCategoryData subcategoryData = new SubCategoryData(NodeTypeEnum.ResourceSubcategory); + subcategoryData.getSubCategoryDataDefinition().setName(subcategory); + subcategoryData.getSubCategoryDataDefinition() + .setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(subcategory)); + subcategoryData.getSubCategoryDataDefinition().setUniqueId(UniqueIdBuilder + .buildSubCategoryUid(categoryData.getCategoryDataDefinition().getUniqueId(), subcategory)); + titanDao.deleteNode(categoryData, CategoryData.class); + titanDao.deleteNode(subcategoryData, SubCategoryData.class); + Either createNode = titanDao.createNode(categoryData, CategoryData.class); + titanDao.createNode(subcategoryData, SubCategoryData.class); + titanDao.createRelation(categoryData, subcategoryData, GraphEdgeLabels.SUB_CATEGORY, null); + return (String) createNode.left().value().getUniqueId(); + } + + public static void deleteServiceCategory(String category, TitanGenericDao titanDao) { + ServiceCategoryData categoryData = new ServiceCategoryData(category); + titanDao.deleteNode(categoryData, ServiceCategoryData.class); + } + + public static void deleteResourceCategory(String category, String subcategory, TitanGenericDao titanDao) { + ResourceCategoryData categoryData = new ResourceCategoryData(category, subcategory); + titanDao.deleteNode(categoryData, ResourceCategoryData.class); + } + + public static User convertUserDataToUser(UserData modifierData) { + User modifier = new User(); + modifier.setUserId(modifierData.getUserId()); + modifier.setEmail(modifierData.getEmail()); + modifier.setFirstName(modifierData.getFirstName()); + modifier.setLastName(modifierData.getLastName()); + modifier.setRole(modifierData.getRole()); + return modifier; + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/PrintGraph.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/PrintGraph.java new file mode 100644 index 0000000000..b58ce5598d --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/PrintGraph.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.be.model.operations.impl.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +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.Property; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; +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 com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanGraph; +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; + +public class PrintGraph { + + public void printGraphVertices(TitanGraph graph) { + + Iterable vertices = graph.query().vertices(); + + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + // System.out.println(vertex); + // System.out.println(ElementHelper.getProperties(vertex)); + // System.out.println("======================================="); + } + + } + // graph.commit(); + graph.tx().commit(); + } + + public void printGraphEdges(TitanGraph graph) { + + Iterable vertices = graph.query().edges(); + + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + Edge edge = iterator.next(); + + // System.out.println(edge); + // System.out.println("edge=" + edge.getLabel() + ", + // properties="+ ElementHelper.getProperties(edge)); + // System.out.println("edge=" + edge.label() + ", properties="+ + // getProperties(edge)); + // System.out.println("======================================="); + } + + } + // graph.commit(); + graph.tx().commit(); + } + + public String buildGraphForWebgraphWiz(TitanGraph graph) { + + StringBuilder builder = new StringBuilder(); + builder.append("digraph finite_state_machine {\n"); + builder.append("rankdir=LR;\n"); + builder.append("size=\"15,10\" \n"); + // node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8; + // node [shape = circle]; + + Iterable vertices = graph.query().vertices(); + + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + // System.out.println(vertex); + // System.out.println(ElementHelper.getProperties(vertex)); + // System.out.println(getProperties(vertex)); + // System.out.println("======================================="); + + Map properties = getProperties(vertex); + + String nodeLabel = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()); + + String color = getColorByNodeType(nodeLabel); + + String uid = getNodeIdByLabel(nodeLabel, properties); + + // System.out.println("uid=" + uid); + + String nodeRecord = buildNodeRecord(uid, color, properties); + + // System.out.println(nodeRecord); + + builder.append(nodeRecord); + + // if (nodeLabel.equals(NodeTypeEnum.Category)) { + // + // String + // + // } else (nodeLabel.equals(NodeTypeEnum.User)) { + // + // } + + } + + } + + Iterable edges = graph.query().edges(); + + if (edges != null) { + Iterator iterator = edges.iterator(); + while (iterator.hasNext()) { + Edge edge = iterator.next(); + + // Vertex vertexFrom = edge.getVertex(Direction.OUT); + // Vertex vertexTo = edge.getVertex(Direction.IN); + Vertex vertexFrom = edge.outVertex(); + Vertex vertexTo = edge.inVertex(); + + // String fromUid = + // getNodeIdByLabel((String)vertexFrom.getProperty(GraphPropertiesDictionary.LABEL.getProperty()), + // ElementHelper.getProperties(vertexFrom)); + // String toUid = + // getNodeIdByLabel((String)vertexTo.getProperty(GraphPropertiesDictionary.LABEL.getProperty()), + // ElementHelper.getProperties(vertexTo)); + String fromUid = getNodeIdByLabel(vertexFrom.value(GraphPropertiesDictionary.LABEL.getProperty()), + getProperties(vertexFrom)); + String toUid = getNodeIdByLabel(vertexTo.value(GraphPropertiesDictionary.LABEL.getProperty()), + getProperties(vertexTo)); + + // String edgeLabel = edge.getLabel(); + String edgeLabel = edge.label(); + + // String edgeRecord = buildEdgeRecord(fromUid, toUid, + // edgeLabel, ElementHelper.getProperties(edge)); + String edgeRecord = buildEdgeRecord(fromUid, toUid, edgeLabel, getProperties(edge)); + + builder.append(edgeRecord); + + // System.out.println(edge); + // System.out.println("edge=" + edge.getLabel() + ", + // properties=" + // + ElementHelper.getProperties(edge)); + // System.out.println("edge=" + edge.label() + ", properties=" + // + getProperties(edge)); + // System.out.println("======================================="); + } + + } + + builder.append(" } "); + + return builder.toString(); + + } + + // LR_0 [ style = "bold" color = "red" shape = "Mrecord" label = + // "hello\nworld | { name | apache } | { version | 1.0 } | { uid | + // apache.1.0 } | { state| CERTIFIED } |{ b |{c| d|e}| f}| g | h" + // ] + + // LR_0 -> LR_2 [ label = "SS(B)" ]; + // LR_0 -> LR_1 [ label = "SS(S)" ]; + // LR_1 -> LR_3 [ label = "S($end)" ]; + // LR_2 -> LR_6 [ label = "SS(b)" ]; + // LR_2 -> LR_5 [ label = "SS(a)" ]; + // LR_2 -> LR_4 [ label = "S(A)" ]; + // LR_5 -> LR_7 [ label = "S(b)" ]; + // LR_5 -> LR_5 [ label = "S(a)" ]; + // LR_6 -> LR_6 [ label = "S(b)" ]; + // LR_6 -> LR_5 [ label = "S(a)" ]; + // LR_7 -> LR_8 [ label = "S(b)" ]; + // LR_7 -> LR_5 [ label = "S(a)" ]; + // LR_8 -> LR_6 [ label = "S(b)" ]; + // LR_8 -> LR_5 [ label = "S(a)" ]; + + private String buildEdgeRecord(String fromUid, String toUid, String edgeLabel, Map properties) { + + StringBuilder builder = new StringBuilder(); + // LR_0 -> LR_2 [ label = "SS(B)" ]; + + String generatedProps = generateStringFromProperties(properties); + + String color = getEdgeColorByLabel(edgeLabel); + + builder.append("\"" + fromUid + "\"" + " -> " + "\"" + toUid + "\"" + " [ color = " + color + " label = \"" + + edgeLabel + "(" + generatedProps + ")\"" + " ] " + "\n"); + + return builder.toString(); + } + + private String getEdgeColorByLabel(String edgeLabel) { + + GraphEdgeLabels edgeLabelEnum = GraphEdgeLabels.getByName(edgeLabel); + + String color = "black"; + + switch (edgeLabelEnum) { + case PROPERTY: + color = "orange"; + break; + case CAPABILITY: + break; + case DERIVED_FROM: + color = "red"; + default: + break; + } + + return color; + } + + private String generateStringFromProperties(Map properties) { + + StringBuilder builder = new StringBuilder(); + + if (properties != null) { + for (Entry entry : properties.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue().toString(); + builder.append(key + "=" + value + "__"); + } + } + return builder.toString(); + + } + + private String buildNodeRecord(String uid, String color, Map properties) { + + StringBuilder builder = new StringBuilder(); + + builder.append("\"" + uid + "\"" + " [ "); + builder.append("style = \"bold\" "); + builder.append(" color = \"" + color + "\""); + builder.append("shape = \"Mrecord\" "); + + String label = ""; + int maxKeyLength = 0; + for (Entry entry1 : properties.entrySet()) { + String key = entry1.getKey(); + int keyLength = key.length(); + if (keyLength > maxKeyLength) { + maxKeyLength = keyLength; + } + } + + boolean first = true; + for (Entry entry : properties.entrySet()) { + + String key = entry.getKey(); + String value = entry.getValue().toString(); + + if (key.equals(GraphPropertiesDictionary.CONSTRAINTS.getProperty())) { + value = value.replaceAll("[^\\w\\s]", "_"); + } + + key = padKey(key, maxKeyLength); + + if (first) { + first = false; + } else { + label += " | "; + } + label += " { " + key + " | " + value + " } "; + } + + builder.append("label = \"" + label + "\" "); + builder.append(" ] "); + + // LR_0 [ style = "bold" color = "red" shape = "Mrecord" label = + // "hello\nworld | { name | apache } | { version | 1.0 } | { uid | + // apache.1.0 } | { state| CERTIFIED } |{ b |{c| d|e}| f}| g | h" + // ] + + builder.append(" \n "); + return builder.toString(); + } + + private String getNodeIdByLabel(String nodeLabel, Map properties) { + + NodeTypeEnum typeEnum = NodeTypeEnum.getByName(nodeLabel); + + String uid = null; + switch (typeEnum) { + + case User: + uid = (String) properties.get(GraphPropertiesDictionary.USER_ID.getProperty()); + break; + case ServiceCategory: + case ResourceCategory: + case Tag: + uid = (String) properties.get(GraphPropertiesDictionary.NAME.getProperty()); + break; + + default: + uid = (String) properties.get(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + break; + } + + return uid; + } + + private String getColorByNodeType(String nodeLabel) { + + NodeTypeEnum typeEnum = NodeTypeEnum.getByName(nodeLabel); + + String color = "red"; + switch (typeEnum) { + case ServiceCategory: + color = "blue"; + break; + case ResourceCategory: + color = "blue"; + break; + case Resource: + color = "forestgreen"; + break; + case User: + color = "green"; + break; + case Capability: + color = "lightgreen"; + break; + case CapabilityType: + color = "gray"; + break; + case Property: + color = "cyan"; + break; + case RelationshipType: + color = "darkorchid"; + break; + case Requirement: + color = "gold"; + break; + case RequirementImpl: + // color = "forestgreen"; + color = "gold"; + break; + case Service: + color = "cyan4"; + break; + case Tag: + color = "dimgrey"; + break; + default: + break; + + } + + return color; + } + + private String padKey(String key, int maxKeyLength) { + + int len = key.length(); + for (int i = len; i < maxKeyLength; i++) { + key += " "; + } + + return key; + } + + public int getNumberOfVertices(TitanGraph graph) { + int counter = 0; + Iterable vertices = graph.query().vertices(); + + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + counter++; + } + } + return counter; + } + + public Set getVerticesSet(TitanGraph titanGraph) { + + Set set = new HashSet(); + + Iterable vertices = titanGraph.query().vertices(); + + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + // System.out.println(vertex); + // System.out.println(ElementHelper.getProperties(vertex)); + // System.out.println(getProperties(vertex)); + // System.out.println("======================================="); + + // Map properties = + // ElementHelper.getProperties(vertex); + Map properties = getProperties(vertex); + + String nodeLabel = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()); + + String uid = getNodeIdByLabel(nodeLabel, properties); + + set.add(uid); + } + } + + return set; + + } + + public Map getProperties(Element element) { + + Map result = null; + + if (element.keys() != null && element.keys().size() > 0) { + Map propertyMap = ElementHelper.propertyMap(element, + element.keys().toArray(new String[element.keys().size()])); + result = new HashMap(); + + for (Entry entry : propertyMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue().value(); + + result.put(key, value); + } + } + return result; + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/ResourceCreationUtils.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/ResourceCreationUtils.java new file mode 100644 index 0000000000..b6b951bdc4 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/ResourceCreationUtils.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.model.operations.impl.util; + +public class ResourceCreationUtils { + + public static String ATT_UID = "jm007a"; + public static String FIRST_NAME = "Julia"; + public static String LAST_NAME = "Hendrix"; + public static String DEFAULT_RESOURCE_NAME = "my-resource"; + public static String DEFAULT_RESOURCE_VERSION = "1.0"; + public static String DEFAULT_USER_ID = "jh0003"; + + public static String MODIFIER_ATT_UID = "jk9990"; + public static String MODIFIER_FIRST_NAME = "Roki"; + public static String MODIFIER_LAST_NAME = "Balaboa"; + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/serialize/TestResourceSerialization.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/serialize/TestResourceSerialization.java new file mode 100644 index 0000000000..699e23affd --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/serialize/TestResourceSerialization.java @@ -0,0 +1,222 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.model.serialize; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringJoiner; +import java.util.stream.Collectors; + +import org.junit.Test; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.common.util.SerializationUtils; + +import fj.data.Either; + +public class TestResourceSerialization { + + // @Test + public void findAllClassesUsedByResource() { + + Set classesWithoutSerialzable = new HashSet<>(); + Set classestoIgnore = new HashSet<>(); + classestoIgnore.add("java.util.List"); + classestoIgnore.add("java.util.Map"); + classestoIgnore.add("long"); + + Set allClasses = new HashSet<>(); + findAllClassesUsedByResource(Resource.class, allClasses); + ArrayList l; + for (Class clazz : allClasses) { + Class[] interfaces = clazz.getInterfaces(); + if (interfaces != null) { + String collect = Arrays.stream(interfaces).map(p -> p.getName()).collect(Collectors.joining("\n")); + + Class orElse = Arrays.stream(interfaces).filter(p -> p.getName().equals("java.io.Serializable")) + .findAny().orElse(null); + if (orElse == null) { + classesWithoutSerialzable.add(clazz); + } + + } + } + + List collect = classesWithoutSerialzable.stream() + .filter(p -> false == classestoIgnore.contains(p.getName())).collect(Collectors.toList()); + + if (collect != null) { + System.out.println(collect.stream().map(p -> p.getName()).collect(Collectors.joining("\n"))); + assertEquals("check all classes implements Serializable", 0, collect.size()); + } + + } + + public void findAllClassesUsedByResource(Class clazz, Set allClasses) { + + Class superclass = clazz.getSuperclass(); + findAllClassesOfClass(clazz, allClasses); + + if (superclass != null) { + findAllClassesOfClass(superclass, allClasses); + } + + } + + public void findAllClassesOfClass(Class clazz, Set allClasses) { + + Field[] fields = clazz.getDeclaredFields(); + if (fields != null) { + for (Field field : fields) { + String name = field.getName(); + Class type = field.getType(); + + if (type.toString().contains(".List")) { + ParameterizedType stringListType = (ParameterizedType) field.getGenericType(); + Class stringListClass = (Class) stringListType.getActualTypeArguments()[0]; + // System.out.println(stringListClass); // class + // java.lang.String. + allClasses.add(stringListClass); + } + + if (type.toString().contains("java.util.Map")) { + ParameterizedType stringListType = (ParameterizedType) field.getGenericType(); + + Type[] actualTypeArguments = stringListType.getActualTypeArguments(); + if (actualTypeArguments != null) { + for (Type actualType : actualTypeArguments) { + + String typeName = actualType.getTypeName(); + // System.out.println("field " + name + "," + + // typeName); + + if (typeName.startsWith("java.util.List<")) { + String internalClass = typeName.replace("java.util.List<", "").replace(">", ""); + // create class from string + Class myClass; + try { + myClass = Class.forName(internalClass); + allClasses.add(myClass); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + assertTrue("Failed to convert " + internalClass + " to class", false); + } + + } else { + try { + Class myClass = Class.forName(typeName); + allClasses.add(myClass); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + assertTrue("Failed to convert " + typeName + " to class", false); + } + + } + } + } + + } + + // System.out.println(type); + allClasses.add(type); + } + } + + } + + private void addInternalTypeOfList(Class clazz) { + + // clazz. + // ParameterizedType stringListType = (ParameterizedType) + // field.getGenericType(); + // Class stringListClass = (Class) + // stringListType.getActualTypeArguments()[0]; + // //System.out.println(stringListClass); // class java.lang.String. + // allClasses.add(stringListClass); + // + } + + private boolean isClassImplementedSerialize(Class clazz) { + + Type[] genericInterfaces = clazz.getGenericInterfaces(); + if (genericInterfaces != null) { + Type orElse = Arrays.stream(genericInterfaces).filter(p -> p.getTypeName().equals("java.io.Serializable")) + .findAny().orElse(null); + if (orElse != null) { + return true; + } + } + + return false; + } + + // @Test + public void testSimpleResourceSerialize() { + + Resource resource = new Resource(); + String name = "res1"; + Map allVersions = new HashMap(); + allVersions.put("keya", "valuea"); + + resource.setName(name); + // all versions + resource.setAllVersions(allVersions); + List resourceInstances = new ArrayList(); + // component instances + ComponentInstance componentInstance = new ComponentInstance(); + componentInstance.setDescription("desc1"); + componentInstance.setComponentUid("comUid"); + resourceInstances.add(componentInstance); + + resource.setComponentInstances(resourceInstances); + + Either serialize = SerializationUtils.serialize(resource); + assertTrue("check object serialized", serialize.isLeft()); + byte[] value = serialize.left().value(); + + Either deserialize = SerializationUtils.deserialize(value); + assertTrue("check object deserialized", deserialize.isLeft()); + Object obj = deserialize.left().value(); + Resource desResource = (Resource) obj; + assertEquals("check name", name, desResource.getName()); + verifyAllVersions(desResource); + + } + + private void verifyAllVersions(Resource desResource) { + assertNotNull("check all versions", desResource.getAllVersions()); + assertEquals("check all version size", 1, desResource.getAllVersions().size()); + assertEquals("check all version key", "keya", desResource.getAllVersions().keySet().iterator().next()); + assertEquals("check all version value", "valuea", desResource.getAllVersions().values().iterator().next()); + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidatorTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidatorTest.java new file mode 100644 index 0000000000..2dfe9a8de7 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidatorTest.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.be.model.tosca.validators; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; +import javax.validation.constraints.AssertTrue; + +import org.junit.Test; +import org.openecomp.sdc.be.model.tosca.validators.IntegerValidator; + +public class IntegerValidatorTest { + private static IntegerValidator validator = IntegerValidator.getInstance(); + + @Test + public void testIntegerValidatorDecimal() { + assertTrue(validator.isValid(null, null)); + assertTrue(validator.isValid("", null)); + assertTrue(validator.isValid("0", null)); + assertTrue(validator.isValid("+0", null)); + assertTrue(validator.isValid("-0", null)); + assertTrue(validator.isValid("+65465", null)); + assertTrue(validator.isValid("-65465", null)); + assertTrue(validator.isValid("2147483647", null)); + assertFalse(validator.isValid("2147483648", null)); + assertTrue(validator.isValid("-2147483648", null)); + assertFalse(validator.isValid("-2147483649", null)); + } + + @Test + public void testIntegerValidatorHexa() { + assertTrue(validator.isValid("-0xadc", null)); + assertTrue(validator.isValid("+0xadf", null)); + assertTrue(validator.isValid("0x7FFFFFFF", null)); + assertFalse(validator.isValid("0x80000000", null)); + assertTrue(validator.isValid("-0x80000000", null)); + assertFalse(validator.isValid("-0x80000001", null)); + } + + public void testIntegerValidatorOctal() { + assertTrue(validator.isValid("0o545435", null)); + assertTrue(validator.isValid("-0o545435", null)); + assertTrue(validator.isValid("0o17777777777", null)); + assertFalse(validator.isValid("0o20000000000", null)); + assertTrue(validator.isValid("-0o20000000000", null)); + assertFalse(validator.isValid("-0o20000000001", null)); + } + + @Test + public void testIntegerValidatorIncorrect() { + assertFalse(validator.isValid("-2.147483649", null)); + assertFalse(validator.isValid("dsfasf342342", null)); + } +} diff --git a/catalog-model/src/test/resources/application-context-test.xml b/catalog-model/src/test/resources/application-context-test.xml new file mode 100644 index 0000000000..43f4b088e4 --- /dev/null +++ b/catalog-model/src/test/resources/application-context-test.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/catalog-model/src/test/resources/config/ecomp-error-configuration.yaml b/catalog-model/src/test/resources/config/ecomp-error-configuration.yaml new file mode 100644 index 0000000000..f8639668ee --- /dev/null +++ b/catalog-model/src/test/resources/config/ecomp-error-configuration.yaml @@ -0,0 +1,308 @@ +########################################### +# 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: WARN, + description: "Error during BE Health Check", + alarmSeverity: INFORMATIONAL + } + + 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 + } + + BeUebConnectionError: { + type: CONNECTION_PROBLEM, + code: ASDC_4004, + severity: ERROR, + description: "Connection problem towards U-EB server.", + 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 + } + + + # last error code: ASDC_4021 \ No newline at end of file diff --git a/catalog-model/src/test/resources/logback-test.xml b/catalog-model/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..d2b9bff23f --- /dev/null +++ b/catalog-model/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 -- cgit 1.2.3-korg