aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--asdctool/src/main/resources/config/error-configuration.yaml1321
-rw-r--r--catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml15
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java28
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/DefaultExceptionMapper.java9
-rw-r--r--catalog-be/src/main/resources/config/error-configuration.yaml14
-rw-r--r--catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml22
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java4
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/exception/OperationException.java38
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/exception/supplier/DataTypeOperationExceptionSupplier.java20
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/PropertyDefinitionDto.java2
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/mapper/PropertyDefinitionDtoMapper.java17
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java29
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java16
-rw-r--r--catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java95
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html18
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts80
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts51
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.html66
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.less104
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.spec.ts88
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.ts233
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html37
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.less10
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.spec.ts5
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts238
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.html2
-rw-r--r--catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.module.ts14
-rw-r--r--catalog-ui/src/app/ng2/services/data-type.service.ts5
-rw-r--r--catalog-ui/src/app/utils/constants.ts1
-rw-r--r--catalog-ui/src/app/utils/tosca-type-helper.ts78
-rw-r--r--catalog-ui/src/assets/languages/en_US.json16
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java17
32 files changed, 2321 insertions, 372 deletions
diff --git a/asdctool/src/main/resources/config/error-configuration.yaml b/asdctool/src/main/resources/config/error-configuration.yaml
index e201f8979a..f8efb0b4e0 100644
--- a/asdctool/src/main/resources/config/error-configuration.yaml
+++ b/asdctool/src/main/resources/config/error-configuration.yaml
@@ -8,6 +8,10 @@ errors:
code: 201,
message: "OK"
}
+ ACCEPTED: {
+ code: 202,
+ message: "Accepted"
+ }
NO_CONTENT: {
code: 204,
message: "No Content"
@@ -42,6 +46,18 @@ errors:
message: "Error: Not authorized to use the API.",
messageId: "POL5003"
}
+ #---------POL5004------------------------------
+ MISSING_USER_ID: {
+ code: 400 ,
+ message: "Error: Missing 'USER_ID' HTTP header.",
+ messageId: "POL5004"
+ }
+ #---------POL5005------------------------------
+ SESSION_EXPIRED: {
+ code: 403 ,
+ message: "Your session has expired. Please close the SDC tab and re-enter the SDC application.",
+ messageId: "POL5005"
+ }
#---------SVC4000-----------------------------
INVALID_CONTENT: {
code: 400,
@@ -55,7 +71,7 @@ errors:
messageId: "SVC4002"
}
#---------SVC4003------------------------------
- # %1 - Users's USER_ID
+ # %1 - Users's ID
USER_NOT_FOUND: {
code: 404,
message: "Error: User '%1' was not found.",
@@ -89,17 +105,23 @@ errors:
messageId: "SVC4007"
}
#---------SVC4008-----------------------------
- # %1 - Users's USER_ID
+ # %1 - Users's userId
INVALID_USER_ID: {
code: 400,
- message: "Error: Invalid USER_ID '%1'.",
+ message: "Error: Invalid userId '%1'.",
messageId: "SVC4008"
}
+ #---------SVC4009-----------------------------
+ USER_DEFINED: {
+ code: 400,
+ message: "Error: User Defined '%1'.",
+ messageId: "SVC4009"
+ }
#---------SVC4049------------------------------
# %1 - service/resource
COMPONENT_MISSING_CONTACT: {
code: 400,
- message: "Error: Invalid Content. Missing %1 Contact Id.",
+ message: "Error: Invalid Content. Missing %1 contact.",
messageId: "SVC4049"
}
#---------SVC4050-----------------------------
@@ -202,14 +224,14 @@ errors:
}
#---------SVC4064------------------------------
- # %1 - Service/Resource
+ # %1 - Service/Resource/Property
COMPONENT_INVALID_DESCRIPTION: {
code: 400,
message: "Error: Invalid Content. %1 description contains non-english characters.",
messageId: "SVC4064"
}
#---------SVC4065------------------------------
- # %1 - Service/Resource
+ # %1 - Service/Resource/Property
# %2 - max resource/service name length
COMPONENT_DESCRIPTION_EXCEEDS_LIMIT: {
code: 400,
@@ -242,7 +264,7 @@ errors:
# %1 - Service/Resource/Product
COMPONENT_INVALID_CONTACT: {
code: 400,
- message: "Error: Invalid Content. %1 Contact Id should be in format 'mnnnnnn' or 'aannna' or 'aannnn', where m=m ,a=a-zA-Z and n=0-9",
+ message: "Error: Invalid Content. %1 Contact Id should be in format 'mnnnnnn' or 'aannna' or 'aannnn', where m=m ,a=a-zA-Z and n=0-9. Max length: 50",
messageId: "SVC4069"
}
#---------SVC4070------------------------------
@@ -340,7 +362,7 @@ errors:
# %2  - resource/service
COMPONENT_IN_USE: {
code: 403,
- message: "Error: Requested '%1' %2 is in use by another user.",
+ message: "Error: '%1' %2 is still held by previous action. Please try again later.",
messageId: "SVC4086"
}
#-----------SVC4087---------------------------
@@ -441,7 +463,7 @@ errors:
# %1 - User's USER_ID
USER_INACTIVE: {
code: 404,
- message: "Error: User %1 was not found.",
+ message: "Error: User %1 inactive.",
messageId: "SVC4120"
}
#-----------SVC4121---------------------------
@@ -506,7 +528,7 @@ errors:
#-----------SVC4130---------------------------
INVALID_PROJECT_CODE: {
code: 400,
- message: "Error: Invalid Content. PROJECT_CODE must be from 3 up to 50 characters.",
+ message: "Error: Invalid Content. PROJECT_CODE must be from 5 up to 50 characters.",
messageId: "SVC4130"
}
#-----------SVC4131---------------------------
@@ -565,13 +587,6 @@ errors:
message: "Error: Invalid distribution environment.",
messageId: "SVC4138"
}
- #---------SVC4139------------------------------
- # %1 - service name
- DISTRIBUTION_ARTIFACT_NOT_FOUND: {
- code: 409,
- message: "Error: Service '%1' cannot be distributed due to missing deployment artifacts.",
- messageId: "SVC4139"
- }
#---------SVC4200------------------------------
# %1 - Service/Resource
# %2 - max icon name length
@@ -907,38 +922,19 @@ errors:
message: "Error: Invalid resource checksum.",
messageId: "SVC4549"
}
- #---------SVC4550------------------------------
- #%1  -  Consumer salt
- INVALID_LENGTH: {
- code: 400,
- message: "Error: Invalid %1 length.",
- messageId: "SVC4550"
- }
#---------SVC4551------------------------------
- #%1  -  ECOMP User name
+ # %1  -  ECOMP User name
ECOMP_USER_NOT_FOUND: {
code: 404,
message: "Error: ECOMP User '%1' was not found.",
messageId: "SVC4551"
}
- #---------SVC4552------------------------------
- CONSUMER_ALREADY_EXISTS: {
- code: 409,
- message: "Error: ECOMP User already exists.",
- messageId: "SVC4552"
- }
- #---------SVC4553-----------------------------
- #%1  -  Consumer name / Consumer password/ Consumer salt
- INVALID_CONTENT_PARAM: {
- code: 400,
- message: "Error: %1 is invalid.",
- messageId: "SVC4553"
- }
#---------SVC4554------------------------------
- # %1 - "Resource"/"Service"
+ # %1 - Artifact Id
+ # %2 - "Resource"/"Service"
COMPONENT_ARTIFACT_NOT_FOUND: {
code: 404,
- message: "Error: Requested artifact doesn't belong to specified %1.",
+ message: "Error: Requested artifact %1 doesn't belong to specified %2.",
messageId: "SVC4554"
}
#---------SVC4554------------------------------
@@ -949,24 +945,24 @@ errors:
messageId: "SVC4554"
}
#---------SVC4555------------------------------
- #%1 - "Resource"/"Service"/"Product"
- #%2 - "category"
+ # %1 - "Resource"/"Service"/"Product"
+ # %2 - "category"
COMPONENT_ELEMENT_INVALID_NAME_LENGTH: {
code: 400,
message: "Error: Invalid %1 %2 name length.",
messageId: "SVC4555"
}
#---------SVC4556------------------------------
- #%1 - "Resource"/"Service"/"Product"
- #%2 - "category"
+ # %1 - "Resource"/"Service"/"Product"
+ # %2 - "category"
COMPONENT_ELEMENT_INVALID_NAME_FORMAT: {
code: 400,
message: "Error: Invalid %1 %2 name format.",
messageId: "SVC4556"
}
#---------SVC4557------------------------------
- #%1 - "Resource"/"Service"/"Product"
- #%2 - "category name"
+ # %1 - "Resource"/"Service"/"Product"
+ # %2 - "category name"
COMPONENT_CATEGORY_ALREADY_EXISTS: {
code: 409,
message: "Error: %1 category name '%2' already exists.",
@@ -1054,16 +1050,16 @@ errors:
message: "Error: Uploaded XML file for %1 artifact is invalid.",
messageId: "SVC4567"
}
- #---------SVC4567------------------------------
- # %1 - "User Name and USER_ID"
- # %2 -"checked-out"/"in-certification"
+ #---------SVC4569------------------------------
+ # %1 - "User Name and UserId"
+ # %2 -"component names ot IDs"
CANNOT_DELETE_USER_WITH_ACTIVE_ELEMENTS: {
- code: 409,
- message: "Error: User cannot be deleted. User '%1' has %2 projects.",
- messageId: "SVC4567"
+ code: 412,
+ message: "Error: User cannot be deleted. User '%1' has projects that cannot be committed: %2.",
+ messageId: "SVC4569"
}
#---------SVC4568------------------------------
- # %1 - "User Name and USER_ID"
+ # %1 - "User Name and UserId"
# %2 -"checked-out"/"in-certification"
CANNOT_UPDATE_USER_WITH_ACTIVE_ELEMENTS: {
code: 409,
@@ -1139,7 +1135,7 @@ errors:
messageId: "SVC4580"
}
#---------SVC4581------------------------------
- # %1 - USER_ID
+ # %1 - UserId
INVALID_PRODUCT_CONTACT: {
code: 400,
message: "Error: Invalid content. User '%1' cannot be set as Product Contact.",
@@ -1317,7 +1313,7 @@ errors:
# %3 - state
ILLEGAL_COMPONENT_STATE: {
code: 403,
- message: "Error: Component instance of %1 can not be created because the component '%2' is in an illegal state %3.",
+ message: "Error: Action is not allowed on %1 '%2' because it is in an illegal state %3.",
messageId: "SVC4603"
}
#---------SVC4604------------------------------
@@ -1420,7 +1416,7 @@ errors:
# %4 - component type [VF ]
GROUP_INVALID_COMPONENT_INSTANCE: {
code: 400,
- message: "Error: member %1 listed in group %2 is not part of %3 %4.",
+ message: "Error: Member '%1' listed in group '%2' is not part of '%3' %4.",
messageId: "SVC4616"
}
#---------SVC4617------------------------------
@@ -1652,7 +1648,7 @@ errors:
# %1 - "groupName"
INVALID_VF_MODULE_NAME: {
code: 400,
- message: "Error: Invalid Content. VF Module name '%1' contains invalid characters",
+ message: "Error: Invalid Content. Group name '%1' contains invalid characters",
messageId: "SVC4646"
}
@@ -1663,132 +1659,1185 @@ errors:
message: "Error: Invalid VF Module name modification, can not modify '%1'",
messageId: "SVC4647"
}
+ #---------SVC4648------------------------------
+ # %1 - "inputId"
+ # %2 - "componentId"
+ INPUT_IS_NOT_CHILD_OF_COMPONENT: {
+ code: 400,
+ message: "Error: Input id: '%1' is not child of component id: '%2'",
+ messageId: "SVC4648"
+ }
+ #---------SVC4649------------------------------
+ # %1 - "groupName"
+ GROUP_HAS_CYCLIC_DEPENDENCY: {
+ code: 400,
+ message: "Error: The group '%1' has cyclic dependency",
+ messageId: "SVC4649"
+ }
+ #---------SVC4650------------------------------
+ # %1 - "Component Type"
+ # %2 - <ServiceName>
+ # %3 - error description
+ AAI_ARTIFACT_GENERATION_FAILED: {
+ code: 500,
+ message: "Error: %1 %2 automatic generation of artifacts failed. Description: %3",
+ messageId: "SVC4650"
+ }
+ #---------SVC4651------------------------------
+ PARENT_RESOURCE_DOES_NOT_EXTEND: {
+ code: 400,
+ message: "Error: Once resource is certified, derived_from can be changed only to a sibling",
+ messageId: "SVC4651"
+ }
+ #---------SVC4652------------------------------
+ # %1 - resource/service
+ COMPONENT_INVALID_SUBCATEGORY: {
+ code: 400,
+ message: "Error: Invalid Content. Invalid %1 sub category.",
+ messageId: "SVC4652"
+ }
+ #---------SVC4653------------------------------
+ # %1 - group instance uniqueId
+ # %2 - service uniqueId
+ GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE: {
+ code: 404,
+ message: "Error: Requested group instance %1 was not found on component %2.",
+ messageId: "SVC4653"
+ }
+ #---------SVC4654------------------------------
+ # %1 - group property name
+ # %2 - valid min limit value
+ # %3 - valid max limit value
+ INVALID_GROUP_MIN_MAX_INSTANCES_PROPERTY_VALUE: {
+ code: 400,
+ message: "Error: Value of %1 must be not higher than %2, and not lower than %3.",
+ messageId: "SVC4654"
+ }
+ #---------SVC4655------------------------------
+ # %1 - group property name
+ # %2 - valid min limit value
+ # %3 - valid max limit value
+ INVALID_GROUP_INITIAL_COUNT_PROPERTY_VALUE: {
+ code: 400,
+ message: "Error: Value of %1 must be between %2 and %3.",
+ messageId: "SVC4655"
+ }
+ #---------SVC4656------------------------------
+ # %1 - group property name
+ # %2 - lower/higher
+ # %3 - valid max/min value
+ INVALID_GROUP_PROPERTY_VALUE_LOWER_HIGHER: {
+ code: 400,
+ message: "Error: Value of %1 must be %2 or equals to %3.",
+ messageId: "SVC4656"
+ }
+ #---------SVC4657------------------------------
+ # %1 - certificationRequest / startTesting
+ RESOURCE_VFCMT_LIFECYCLE_STATE_NOT_VALID: {
+ code: 400,
+ message: "Error - Lifecycle state %1 is not valid for resource of type VFCMT",
+ messageId: "SVC4657"
+ }
+ #---------SVC4658------------------------------
+ # %1 – asset type [service / resource ]
+ # %2 – main asset uuid
+ # %3 – not found asset type [service / resource]
+ # %4 – not found asset name
+ ASSET_NOT_FOUND_DURING_CSAR_CREATION: {
+ code: 400,
+ message: "Error: CSAR packaging failed for %1 %2. %3 %4 was not found",
+ messageId: "SVC4658"
+ }
+ #---------SVC4659------------------------------
+ # %1 – asset type [service / resource ]
+ # %2 – main asset uuid
+ # %3 – Artifact name
+ # %4 – Artifact uuid
+ ARTIFACT_PAYLOAD_NOT_FOUND_DURING_CSAR_CREATION: {
+ code: 400,
+ message: "Error: CSAR packaging failed for %1 %2. Artifact %3 [%4] was not found",
+ messageId: "SVC4659"
+ }
+ #---------SVC4660------------------------------
+ # %1 - assetType
+ # %2 - matching generic node type name
+ GENERIC_TYPE_NOT_FOUND: {
+ code: 404,
+ message: "Creation of %1 failed. Generic type %2 was not found",
+ messageId: "SVC4660"
+ }
+ #---------SVC4661------------------------------
+ # %1 - assetType
+ # %2 - matching generic node type name
+ TOSCA_SCHEMA_FILES_NOT_FOUND: {
+ code: 400,
+ message: "Error: CSAR packaging failed. TOSCA schema files for SDC-Version: %1 and Conformance-Level %2 were not found",
+ messageId: "SVC4661"
+ }
+ #---------SVC4662------------------------------
+ # %1 - file name
+ # %2 - parser error
+ TOSCA_PARSE_ERROR: {
+ code: 400,
+ message: "Error: Invalid TOSCA template in file %1. %2",
+ messageId: "SVC4662"
+ }
+ #---------SVC4663------------------------------
+ # %1 - max length
+ RESOURCE_VENDOR_MODEL_NUMBER_EXCEEDS_LIMIT: {
+ code: 400,
+ message: "Error: Invalid Content. Resource vendor model number exceeds limit of %1 characters.",
+ messageId: "SVC4663"
+ }
+ #---------SVC4664------------------------------
+ INVALID_RESOURCE_VENDOR_MODEL_NUMBER: {
+ code: 400,
+ message: 'Error: Invalid Content. Resource vendor model number is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.',
+ messageId: "SVC4664"
+ }
-
+ #---------SVC4669-----------------------------
+ INVALID_RESOURCE_TYPE: {
+ code: 400,
+ message: "Error: Invalid resource type.",
+ messageId: "SVC4669"
+ }
+ #---------SVC4670------------------------------
+ # %1 - artifactname
+ # %2 - validname
+ ARTIFACT_NAME_INVALID: {
+ code: 400,
+ message: "Error: Artifact name '%1' is invalid. Only the following characters are allowed in the Artifact Name: '%2'.",
+ messageId: "SVC4670"
+ }
+ #---------SVC4671------------------------------
+ # %1 - VSP name
+ # %2 - VFC name
+ CFVC_LOOP_DETECTED: {
+ code: 400,
+ message: 'Error: VSP %1 cannot be imported. The VSP contains internal loop in VFC %2',
+ messageId: "SVC4671"
+ }
+ #---------SVC4672------------------------------
+ # %1 - capability uniqueId
+ # %2 - instance uniqueId
+ # %3 - container uniqueId
+ CAPABILITY_OF_INSTANCE_NOT_FOUND_ON_CONTAINER: {
+ code: 404,
+ message: "Error: Requested capability %1 of instance %2 was not found on the container %3.",
+ messageId: "SVC4672"
+ }
#---------SVC4673------------------------------
- INVALID_SERVICE_STATE: {
- code: 409,
- message: "Error: Invalid service state. Expected state: %1, actual state: %2",
+ # %1 - requirement uniqueId
+ # %2 - instance uniqueId
+ # %3 - container uniqueId
+ REQUIREMENT_OF_INSTANCE_NOT_FOUND_ON_CONTAINER: {
+ code: 404,
+ message: "Error: Requested requirement %1 of instance %2 was not found on the container %3.",
messageId: "SVC4673"
}
-
- #---------SVC4674------------------------------
- INVALID_RESPONSE_FROM_PROXY: {
- code: 502,
- message: "Error: The server was acting as a gateway or proxy and received an invalid response from the upstream server",
+ #---------SVC4674-----------------------------
+ # %1 - relation Id
+ # %2 - container uniqueId
+ RELATION_NOT_FOUND: {
+ code: 404,
+ message: "Error: Requested relation %1 was not found on the container %2.",
messageId: "SVC4674"
}
+
+
#---------SVC4675------------------------------
- # %1 - resource Id
- CAPABILITY_NOT_FOUND: {
- code: 400,
- message: "Error: Capability not found in the resource '%1'.",
+ INVALID_SERVICE_STATE: {
+ code: 409,
+ message: "Service state is invalid for this action",
messageId: "SVC4675"
}
#---------SVC4676------------------------------
- # %1 - resource Id
- REQUIREMENT_NOT_FOUND: {
- code: 400,
- message: "Error: Requirement not found in the resource '%1'.",
+ INVALID_RESPONSE_FROM_PROXY: {
+ code: 502,
+ message: "Error: The server was acting as a gateway or proxy and received an invalid response from the upstream server",
messageId: "SVC4676"
}
- #---------SVC4677-----------------------------
- CAPABILITY_NAME_MANDATORY: {
+
+ #---------SVC4677------------------------------
+ API_RESOURCE_NOT_FOUND: {
code: 404,
- message: "Error: Capability name is mandatory, Capability name can't be empty.",
+ message: "Error: Requested '%1' was not found.",
messageId: "SVC4677"
}
- #---------SVC4678-----------------------------
- CAPABILITY_TYPE_MANDATORY: {
- code: 404,
- message: "Error: Capability type is mandatory, Capability type can't be empty.",
+
+ #---------SVC4678------------------------------
+ BAD_REQUEST_MISSING_RESOURCE: {
+ code: 400,
+ message: "Error: The required resource name/id is missing in the request",
messageId: "SVC4678"
}
- #---------SVC4679-----------------------------
- # %1 - Capability Name
- CAPABILITY_NAME_ALREADY_IN_USE: {
+ #---------SVC4679------------------------------
+ # %1 forwarding path name maximum length
+ FORWARDING_PATH_NAME_MAXIMUM_LENGTH: {
code: 400,
- message: "Error: Capability name '%1' already in use, Your current changes will not be saved.",
+ message: "Forwarding path name too long, , maximum allowed 200 characters : '%1'.",
messageId: "SVC4679"
}
-
- #---------SVC4680-----------------------------
- REQUIREMENT_NAME_MANDATORY: {
- code: 404,
- message: "Error: Requirement name is mandatory, Requirement name can't be empty.",
+ #---------SVC4680------------------------------
+ # %1 Forwarding path name already in use
+ FORWARDING_PATH_NAME_ALREADY_IN_USE: {
+ code: 400,
+ message: "Forwarding path name already in use : '%1'.",
messageId: "SVC4680"
}
- #---------SVC4681-----------------------------
- REQUIREMENT_CAPABILITY_MANDATORY: {
- code: 404,
- message: "Error: Requirement capability is mandatory, Requirement capability can't be empty.",
+ #---------SVC4681------------------------------
+ # %1 Forwarding path name empty
+ FORWARDING_PATH_NAME_EMPTY: {
+ code: 400,
+ message: "Forwarding Path Name can't be empty .",
messageId: "SVC4681"
}
- #---------SVC4682-----------------------------
- # %1 - Requirement Name
- REQUIREMENT_NAME_ALREADY_IN_USE: {
+ #---------SVC4682------------------------------
+ # %1 - resource uniqueId
+ # %2 - resource component type
+ RESOURCE_CANNOT_CONTAIN_POLICIES: {
code: 400,
- message: "Error: Requirement name '%1' already in use, Your current changes will not be saved.",
+ message: "Error: The resource %1 type of %2 cannot contain policies.",
messageId: "SVC4682"
}
- #---------SVC4683-----------------------------
- MAX_OCCURRENCES_SHOULD_BE_GREATER_THAN_MIN_OCCURRENCES: {
- code: 400,
- message: "Error: maxOccurrences should be greater than minOccurrences",
+ #---------SVC4683------------------------------
+ # %1 - policy uniqueId
+ # %2 - component uniqueId
+ POLICY_NOT_FOUND_ON_CONTAINER: {
+ code: 404,
+ message: "Error: Requested policy %1 was not found on the container %2.",
messageId: "SVC4683"
}
- #---------SVC4684-----------------------------
- # %1 - Capability name
- CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION: {
- code: 409,
- message: "Error: Capability '%1' can't be deleted, since it is used in service composition",
+ #---------SVC4684------------------------------
+ # %1 - policy name
+ INVALID_POLICY_NAME: {
+ code: 400,
+ message: "Error: Invalid policy name %1 received.",
messageId: "SVC4684"
}
- #---------SVC4685-----------------------------
- # %1 - Requirement name
- REQUIREMENT_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION: {
+ #---------SVC4801------------------------------
+ # %1 - policy type
+ POLICY_TYPE_IS_INVALID: {
+ code: 400,
+ message: "Error: Invalid content. Policy type %1 does not exist",
+ messageId: "SVC4801"
+ }
+
+ #---------SVC4802------------------------------
+ # %1 - policy name
+ POLICY_MISSING_POLICY_TYPE: {
+ code: 400,
+ message: "Error: Invalid content. Type name is not defined for policy %1",
+ messageId: "SVC4802"
+ }
+
+ #---------SVC4685------------------------------
+ # %1 - policy name
+ POLICY_NAME_ALREADY_EXIST: {
code: 409,
- message: "Error: Requirement '%1' can't be deleted, since it is used in service composition",
+ message: "Error: The policy with the name %1 already exists.",
messageId: "SVC4685"
}
- #---------SVC4686-----------------------------
- CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION: {
- code: 409,
- message: "Error: Capability can't be updated, since it is used in service composition",
+ #---------SVC4686------------------------------
+ # %1 - policy name
+ POLICY_TARGET_DOES_NOT_EXIST: {
+ code: 400,
+ message: "Error: The targets %1 are not valid, all targets have to be on the topologyTemplate.",
messageId: "SVC4686"
}
-
- #---------SVC4687-----------------------------
- REQUIREMENT_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION: {
- code: 409,
- message: "Error: Requirement can't be updated, since it is used in service composition",
+ #---------SVC4687------------------------------
+ # %1 - policy type
+ # %2 - component type
+ EXCLUDED_POLICY_TYPE: {
+ code: 400,
+ message: "Error: The policy of the type %1 excluded to add to a component of the type %2.",
messageId: "SVC4687"
}
- #---------SVC4688-----------------------------
- CAPABILITY_TYPE_CANNOT_BE_EMPTY: {
- code: 500,
- message: "Error: Capability types are empty. Please import the capability types.",
+ #---------SVC4688------------------------------
+ # %1 - group type
+ # %2 - component type
+ GROUP_TYPE_ILLEGAL_PER_COMPONENT: {
+ code: 400,
+ message: "Error: group type %1 not permitted in component of type %2",
messageId: "SVC4688"
}
- #---------SVC4689-----------------------------
- RELATIONSHIP_TYPE_ALREADY_EXIST: {
- code: 409,
- message: "Error: Relationship Type with name '%1' already exists.",
+ #---------SVC4689------------------------------
+ # %1 - group type
+ # %2 - component type
+ POLICY_TARGET_TYPE_DOES_NOT_EXIST: {
+ code: 400,
+ message: "Error: The target types %1 are not valid.",
messageId: "SVC4689"
}
- #---------SVC4690-----------------------------
- # %1 - Requirement name
- INVALID_REQUIREMENT_NAME: {
+
+ #---------SVC4690------------------------------
+ # %1 forwarding path protocol maximum length
+ FORWARDING_PATH_PROTOCOL_MAXIMUM_LENGTH: {
code: 400,
- message: "Requirement name '%1' is invalid, Only alphanumeric chars, underscore and dot allowed",
+ message: "Forwarding path protocol too long, , maximum allowed 200 characters : '%1'.",
messageId: "SVC4690"
}
- #---------SVC4691-----------------------------
- # %1 - Capability name
- INVALID_CAPABILITY_NAME: {
+ #---------SVC4691------------------------------
+ # %1 forwarding path destination port maximum length
+ FORWARDING_PATH_DESTINATION_PORT_MAXIMUM_LENGTH: {
code: 400,
- message: "Capability name '%1' is invalid, Only alphanumeric chars, underscore and dot allowed",
+ message: "Forwarding path destination port too long, , maximum allowed 200 characters : '%1'.",
messageId: "SVC4691"
}
+
+ #---------POL4692------------------------------
+ MISSING_OLD_COMPONENT_INSTANCE: {
+ code: 400 ,
+ message: "Error: Missing 'componentInstanceId' HTTP param.",
+ messageId: "POL4692"
+ }
+
+ #---------POL4693------------------------------
+ MISSING_NEW_COMPONENT_INSTANCE: {
+ code: 400 ,
+ message: "Error: Missing 'newComponentInstanceId' HTTP param.",
+ messageId: "POL4693"
+ }
+
+ #---------SVC4694------------------------------
+ # %1 External Reference Value
+ EXT_REF_NOT_FOUND: {
+ code: 404,
+ message: "Error: External Reference '%1' was not found.",
+ messageId: "SVC4694"
+ }
+ #---------SVC4695-----------------------------
+ # %1 - Interface Operation Name
+ INTERFACE_OPERATION_NAME_ALREADY_IN_USE: {
+ code: 409,
+ message: "Error: Interface Operation name '%1' already in use, Your current changes will not be saved.",
+ messageId: "SVC4695"
+ }
+ #---------SVC4696-----------------------------
+ # %1 - Interface Operation Name
+ INTERFACE_OPERATION_NAME_INVALID: {
+ code: 400,
+ message: "Error: Interface Operation name '%1' is Invalid, Operation name should not contain special character, space and should not be greater than 200 characters.",
+ messageId: "SVC4696"
+ }
+ #---------SVC4697-----------------------------
+ INTERFACE_OPERATION_NAME_MANDATORY: {
+ code: 400,
+ message: "Error: Interface Operation name is mandatory, Operation name can't be empty.",
+ messageId: "SVC4697"
+ }
+ #---------SVC4698-----------------------------
+ # %1 - Interface type
+ INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE: {
+ code: 400,
+ message: "Error: Invalid input, only one operation is allowed in local interface type '%1'.",
+ messageId: "SVC4698"
+ }
+ #---------SVC4699-----------------------------
+ # %1 - Interface Operation input parameter name
+ INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE: {
+ code: 400,
+ message: "Error: Interface Operation input parameter name '%1' already in use, Your current changes will not be saved.",
+ messageId: "SVC4699"
+ }
+ #---------SVC4700-----------------------------
+ INTERFACE_OPERATION_INPUT_NAME_MANDATORY: {
+ code: 400,
+ message: "Error: Interface operation input parameter name should not be empty.",
+ messageId: "SVC4700"
+ }
+ #---------SVC4701-----------------------------
+ # %1 - component Id
+ INTERFACE_OPERATION_NOT_FOUND: {
+ code: 404,
+ message: "Error: Interface operation not found in the component '%1'.",
+ messageId: "SVC4701"
+ }
+ #---------SVC4702-----------------------------
+ INTERFACE_OPERATION_NOT_DELETED: {
+ code: 400,
+ message: "Error: Failed to delete interface operation.",
+ messageId: "SVC4702"
+ }
+ #SVC4732
+ INTERFACE_UNKNOWN: {
+ code: 400,
+ message: "Error: The interface '%1' does not exists in the database.",
+ messageId: "SVC4732"
+ }
+ #SVC4733
+ INTERFACE_OPERATION_NOT_DEFINED: {
+ code: 400,
+ message: "Error: The operation '%1' does not exists in the interface '%2'.",
+ messageId: "SVC4733"
+ }
+ #-----------SVC4692---------------------------
+ RESOURCE_LIFECYCLE_STATE_NOT_VALID: {
+ code: 400,
+ message: "Error: Lifecycle state %1 is not valid for resource",
+ messageId: "SVC4692"
+ }
+ #-----------SVC4693---------------------------
+ #%1 - component name
+ COMPONENT_IS_ARCHIVED: {
+ code: 400,
+ message: "Error: Component %1 is archived",
+ messageId: "SVC4693"
+ }
+ #-----------SVC4703---------------------------
+ #%1 - component name
+ COMPONENT_IS_NOT_HIHGEST_CERTIFIED: {
+ code: 400,
+ message: "Error: Component %1 is not highest certified",
+ messageId: "SVC4703"
+ }
+ #---------SVC4704------------------------------
+ # %1 - "service"/"VF"
+ # %2 - "Resource name"
+ ARCHIVED_ORIGINS_FOUND: {
+ code: 403,
+ message: "Error: Action is not permitted as your '%1' '%2' includes archived resources",
+ messageId: "SVC4704"
+ }
+ #---------SVC4705------------------------------
+ # %1-artifact name
+ ARTIFACT_PAYLOAD_EMPTY: {
+ code: 400,
+ message: "Error: Invalid content. Uploaded file %1 is empty. Please retry with the correct file.",
+ messageId: "SVC4705"
+ }
+ #---------SVC4800------------------------------
+ # %1 - "component id"
+ UPDATE_CATALOG_FAILED: {
+ code: 403,
+ message: "Error: update catalog for component '%1' failed.",
+ messageId: "SVC4800"
+ }
+ #---------SVC4706------------------------------
+ # %1-input(s) name(s) string
+ INPUTS_NOT_FOUND: {
+ code: 400,
+ message: "Error: missing input value(s) %1.",
+ messageId: "SVC4706"
+ }
+ #---------SVC4707-----------------------------
+ # %1 – asset type [service / resource ]
+ # %2 – main asset uuid
+ ERROR_DURING_CSAR_CREATION: {
+ code: 404,
+ message: "Error: CSAR packaging failed for %1 %2.",
+ messageId: "SVC4706"
+ }
+ #---------SVC4708-----------------------------
+ # %1 - Interface Operation input property name, component type
+ INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT: {
+ code: 404,
+ message: "Error: Interface operation input parameter property '%1' not found in '%2' input properties, capability properties or outputs of other operations.",
+ messageId: "SVC4708"
+ }
+ #---------SVC4709-----------------------------
+ # %1 - Interface Operation output parameter name
+ INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE: {
+ code: 400,
+ message: "Error: Interface Operation output parameter name '%1' already in use, Your current changes will not be saved.",
+ messageId: "SVC4708"
+ }
+ #---------SVC4710-----------------------------
+ INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY: {
+ code: 400,
+ message: "Error: Interface operation output parameter name should not be empty.",
+ messageId: "SVC4710"
+ }
+ #---------SVC4711-----------------------------
+ # %1 - interface Id
+ INTERFACE_NOT_FOUND_IN_COMPONENT: {
+ code: 404,
+ message: "Error: Interface not found in the component '%1'.",
+ messageId: "SVC4711"
+ }
+ #---------SVC4709-----------------------------
+ INVALID_PROPERTY_CONSTRAINTS: {
+ # %1 – property constraints type
+ # %2 – received property constraints value
+ # %3 – property type
+ code: 400,
+ message: "Error: Invalid %1 %2 for the type %3 have been received.",
+ messageId: "SVC4709"
+ }
+ #---------SVC4710-----------------------------
+ INVALID_PROPERTY_CONSTRAINTS_FORMAT: {
+ # %1 – received property constraints json section
+ code: 400,
+ message: "Error: Invalid format of the received property constraints section: %1. The property constraints section should be a list.",
+ messageId: "SVC4710"
+ }
+ #---------SVC4711-----------------------------
+ CANNOT_DELETE_VALID_VALUES: {
+ # %1 – property constraints type
+ # %2 – missing valid values
+ code: 400,
+ message: "Error: Deletion of existing %1 is not permitted on an update. Missing values: %2",
+ messageId: "SVC4711"
+ }
+ #---------SVC4712------------------------------
+ MISSING_PROPERTY_NAME: {
+ code: 400 ,
+ message: "Error: Invalid Content. Missing mandatory parameter 'name'." ,
+ messageId: "SVC4712"
+ }
+ #---------SVC4713------------------------------
+ MISSING_PROPERTY_VALUE: {
+ code: 400 ,
+ message: "Error: Invalid Content. Missing mandatory parameter 'value'." ,
+ messageId: "SVC4713"
+ }
+
+ #---------SVC4712---------------------------
+ INVALID_INSTANTIATION_TYPE: {
+ code: 400,
+ message: "Invalid instantiationType: %1",
+ messageId: "SVC4712"
+ }
+
+ #----------SVC4713---------------------------
+ MISSING_ECOMP_GENERATED_NAMING: {
+ code: 400,
+ message: "Missing ecompGeneratedNaming property",
+ messageId: "SVC4713"
+ }
+
+ #-----------SVC4714--------------------------
+ NAMING_POLICY_EXCEEDS_LIMIT: {
+ code: 400,
+ message: "Error: Invalid Content. Naming policy exceeds limit of %1 characters.",
+ messageId: "SVC4714"
+ }
+
+ #---------SVC4715------------------------------
+ INVALID_NAMING_POLICY: {
+ code: 400,
+ message: 'Error: Invalid Content. Naming policy is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.',
+ messageId: "SVC4715"
+ }
+
+ #---------SVC4716------------------------------
+ INVALID_ENVIRONMENT_CONTEXT: {
+ code: 400,
+ message: 'Error: Invalid Environment context: %1',
+ messageId: "SVC4716"
+ }
+
+ #---------SVC4717------------------------------
+ UNSUPPORTED_DISTRIBUTION_STATUS: {
+ code: 400,
+ message: 'Error: Unsupported distribution action: %1',
+ messageId: "SVC4717"
+ }
+ #---------SVC4718------------------------------
+ CONTAINER_CANNOT_CONTAIN_INSTANCE: {
+ # %1 - "container type"
+ # %2- “component type”
+ code: 400 ,
+ message: "Error : %1 can’t contain component instance %2" ,
+ messageId: "SVC4718"
+ }
+ #---------SVC4719------------------------------
+ CONTAINER_CANNOT_CONTAIN_COMPONENT_IN_STATE: {
+ # %1 - "container type"
+ # %2- "lifecycle state"
+ code: 400 ,
+ message: "Error: Container %1 can’t contain component in state %2" ,
+ messageId: "SVC4719"
+ }
+
+ #---------SVC4720------------------------------
+ MISSING_MANDATORY_PROPERTY: {
+ # %1 - "property name"
+ code: 400 ,
+ message: "Error: Missing mandatory %1 property" ,
+ messageId: "SVC4720"
+ }
+
+ #---------SVC4721------------------------------
+ MANDATORY_PROPERTY_MISSING_VALUE: {
+ # %1 - "property name"
+ code: 400 ,
+ message: "Error: Missing value for the mandatory %1 property" ,
+ messageId: "SVC4721"
+ }
+ #---------SVC4712-----------------------------
+ INTERFACE_LIFECYCLE_TYPES_NOT_FOUND: {
+ code: 404,
+ message: "Error: Interface Lifecycle types not found.",
+ messageId: "SVC4712"
+ }
+ #---------SVC4713-----------------------------
+ # %1 - Interface Operation Name
+ INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE: {
+ code: 400,
+ message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'",
+ messageId: "SVC4713"
+ }
+
+ #---------SVC4714-----------------------------
+ NODE_FILTER_NOT_FOUND: {
+ code: 400,
+ message: "Error: Node Filter was not found",
+ messageId: "SVC4714"
+ }
+ #---------SVC4715----------------------------
+ UNSUPPORTED_VALUE_PROVIDED: {
+ code: 400,
+ message: "Error: Supported value type is %1 for %2 property. Provided Value: %3",
+ messageId: "SVC4715"
+ }
+ #---------SVC4716----------------------------
+ # %1 - Property Name
+ SELECTED_PROPERTY_NOT_PRESENT: {
+ code: 400,
+ message: "Error: %1 property does not exists in Service anymore.",
+ messageId: "SVC4716"
+ }
+
+ #---------SVC4184----------------------------
+ # %1 - Source type
+ # %2 - Property Type
+ # %3 - Property Name
+ FILTER_PROPERTY_NOT_FOUND:
+ code: 400
+ message: "%1 %2 %3 does not exist."
+ messageId: "SVC4184"
+
+ #---------SVC4718----------------------------
+ # %1 - Property Name
+ # %2 - Operator Name
+ UNSUPPORTED_OPERATOR_PROVIDED: {
+ code: 400,
+ message: "Error: %1 property does not support %2 operator.",
+ messageId: "SVC4718"
+ }
+
+ #---------SVC4719----------------------------
+ CONSTRAINT_FORMAT_INCORRECT: {
+ code: 400,
+ message: "Error: Constraint provided does not contains expected values.",
+ messageId: "SVC4719"
+ }
+
+ #---------SVC4182----------------------------
+ # %1 - Property Name
+ # %2 - Operator Type
+ SOURCE_TARGET_PROPERTY_TYPE_MISMATCH: {
+ code: 400,
+ message: "Error: Property '%1' type '%2' does not match with property '%3' type '%4'.",
+ messageId: "SVC4182"
+ }
+
+ #---------SVC4721----------------------------
+ # %1 - Property Type
+ # %2 - Operator Type
+ UNSUPPORTED_PROPERTY_TYPE: {
+ code: 400,
+ message: "Error: Property type %1 provided against %2 is not supported for static value.",
+ messageId: "SVC4721"
+ }
+
+ #---------SVC4722------------------------------
+ # %1 Directive value set
+ DIRECTIVES_INVALID_VALUE: {
+ code: 404,
+ message: "Error: Invalid directive value : '%1' .",
+ messageId: "SVC4722"
+ }
+ #---------SVC4723-----------------------------
+ # %1 - Interface Operation output name
+ INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED: {
+ code: 400,
+ message: "Error: Cannot update or delete interface operation output(s) '%1' mapped to an operation input",
+ messageId: "SVC4723"
+ }
+ #---------SVC4724-----------------------------
+ # %1 - Interface Operation output name
+ INTERFACE_OPERATION_DELETE_WITH_MAPPED_OUTPUT: {
+ code: 400,
+ message: "Error: Cannot delete interface operation with output(s) '%1' mapped to another operation input",
+ messageId: "SVC4724"
+ }
+ #---------SVC4725-----------------------------
+ INVALID_CONSUMPTION_TYPE: {
+ code: 400,
+ message: "Error: Given value is different than input type. Needs to be %1",
+ messageId: "SVC4725"
+ }
+ #---------SVC4726-----------------------------
+ INVALID_PROPERTY_VALUES: {
+ code: 400,
+ message: "Error: Invalid property values provided:\n %1",
+ messageId: "SVC4726"
+ }
+ #---------SVC4727------------------------------
+ INVALID_PROPERTY_NAME: {
+ code: 400,
+ message: "Error: Property name contains invalid characters. It should have only letters, numbers and underscores.",
+ messageId: "SVC4727"
+ }
+
+ #---------SVC4728------------------------------
+ FAILED_TO_CREATE_OR_UPDATE_CAPABILITY_PROPERTIES: {
+ code: 500,
+ message: "Error: Failed to create or update capabilities properties",
+ messageId: "SVC4728"
+ }
+
+ #---------SVC4729------------------------------
+ # %1 - resource Id
+ CAPABILITY_PROPERTIES_NOT_FOUND: {
+ code: 400,
+ message: "Error: Capability properties not found in the resource '%1'.",
+ messageId: "SVC4729"
+ }
+ #---------SVC4730------------------------------
+ # %1 - property name
+ PROPERTY_EXCEEDS_LIMIT: {
+ code: 400,
+ message: "Error: Invalid Content. %1 exceeds limit.",
+ messageId: "SVC4722"
+ }
+ #---------SVC4731------------------------------
+ INVALID_PROPERY: {
+ # %1 - property name
+ code: 400,
+ message: 'Error: Invalid Content. %1 has invalid format.',
+ messageId: "SVC4723"
+ }
+ #---------SVC4734------------------------------
+ # %1 - list of validation errors
+ INVALID_PM_DICTIONARY_FILE: {
+ code: 400,
+ message: 'Error: Invalid PM Dictionary File. %1',
+ messageId: "SVC4734"
+ }
+ #-----------SVC4735---------------------------
+ #%1 - input name
+ INPUT_ALREADY_EXIST: {
+ code: 409,
+ message: "Error: Input with '%1' name already exists.",
+ messageId: "SVC4735"
+ }
+ #---------SVC4736------------------------------
+ INVALID_INPUT_NAME: {
+ code: 400,
+ message: "Error: Input name contains invalid characters. It should have only letters, numbers and underscores.",
+ messageId: "SVC4736"
+ }
+ #---------SVC4139------------------------------
+ # %1 - The action that is not supported
+ NOT_SUPPORTED: {
+ code: 400,
+ message: '%1 is not yet supported',
+ messageId: "SVC4139"
+ }
+ #---------SVC4140------------------------------
+ # %1 - Component uid
+ COMPONENT_FIND_ERROR: {
+ code: 500,
+ message: "An unexpected error occurred while retrieving the component '%1'.",
+ messageId: "SVC4140"
+ }
+ #---------SVC4141------------------------------
+ # %1 - Component uid
+ COMPONENT_CAPABILITIES_FIND_ERROR: {
+ code: 500,
+ message: "An unexpected error occurred while retrieving the component '%1' capabilities.",
+ messageId: "SVC4141"
+ }
+ #---------SVC4142------------------------------
+ # %1 - Component uid or name
+ COMPONENT_NOT_FOUND: {
+ code: 404,
+ message: "Component '%1' was not found.",
+ messageId: "SVC4142"
+ }
+ #---------SVC4143------------------------------
+ # %1 - Capability name
+ COMPONENT_INSTANCE_CAPABILITY_UPDATE_ERROR: {
+ code: 500,
+ message: "An unexpected error occurred while updating the capability '%1'.",
+ messageId: "SVC4143"
+ }
+
+ #---------SVC4144------------------------------
+ # %1 - "Model name"
+ MODEL_ALREADY_EXISTS: {
+ code: 409,
+ message: "Error: Model name '%1' already exists.",
+ messageId: "SVC4144"
+ }
+
+ #---------SVC4145------------------------------
+ # %1 - "Model name"
+ INVALID_MODEL: {
+ code: 400,
+ message: "Invalid model '%1'.",
+ messageId: "SVC4145"
+ }
+
+ #---------SVC4146------------------------------
+ MODEL_IMPORTS_IS_EMPTY: {
+ code: 400,
+ message: "Given model imports zip is empty.",
+ messageId: "SVC4146"
+ }
+
+ #---------SVC4147------------------------------
+ COULD_NOT_READ_MODEL_IMPORTS: {
+ code: 400,
+ message: "Could not read imports zip.",
+ messageId: "SVC4147"
+ }
+
+ #---------SVC4148------------------------------
+ # %1 - "Model name"
+ MODEL_NOT_FOUND: {
+ code: 404,
+ message: "Error: Model name '%1' not found. Please, make sure the model is created.",
+ messageId: "SVC4148"
+ }
+
+ #---------SVC4149------------------------------
+ MODEL_NAME_CANNOT_BE_EMPTY: {
+ code: 409,
+ message: "Error: Model name cannot be empty.",
+ messageId: "SVC4149"
+ }
+
+ #-----------SVC4150---------------------------
+ # %1 - "Component name"
+ # %2 - "Model name"
+ COMPONENT_WITH_MODEL_ALREADY_EXIST: {
+ code: 409,
+ message: "Error: Component %1 with Model %2 already exist.",
+ messageId: "SVC4150"
+ }
+ #-----------SVC4151---------------------------
+ # %1 - "Component name"
+ # %2 - "Vendor release"
+ # %3 - "Model name"
+ COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS_IN_MODEL: {
+ code: 409,
+ message: "Error: Component '%1' with Vendor Release '%2' already exists in Model '%3'.",
+ messageId: "SVC4151"
+ }
+ #-----------SVC4152---------------------------
+ # %1 - "Component name"
+ # %2 - "Vendor release"
+ COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS: {
+ code: 409,
+ message: "Error: Component '%1' with Vendor Release '%2' already exists.",
+ messageId: "SVC4152"
+ }
+
+ #-----------SVC4153---------------------------
+ # %1 - "Model name"
+ DATA_TYPES_NOT_LOADED: {
+ code: 500,
+ message: "Could not fetch data types from data base with model %1",
+ messageId: "SVC4153"
+ }
+
+ #-----------SVC4154---------------------------
+ # %1 - "Model name"
+ UNKNOWN_MODEL_TYPE: {
+ code: 400,
+ message: "Error: Model type %1 not known in the system",
+ messageId: "SVC4154"
+ }
+
+ #-----------SVC4154---------------------------
+ CSAR_TOSCA_IMPORTS_ERROR: {
+ code: 500,
+ message: "Error: An error has occurred while including the default TOSCA imports in the CSAR",
+ messageId: "SVC4154"
+ }
+
+ #-----------SVC4155---------------------------
+ # %1 - "VSP id"
+ # %2 - "VSP version id"
+ VSP_FIND_ERROR: {
+ code: 500,
+ message: "An error has occurred while retrieving the Vendor Software Product of id '%1', version id '%2'",
+ messageId: "SVC4155"
+ }
+
+ #-----------SVC4156---------------------------
+ # %1 - "VSP id"
+ # %2 - "VSP version id"
+ VSP_NOT_FOUND: {
+ code: 404,
+ message: "Could not find Vendor Software Product of id '%1', version id '%2'",
+ messageId: "SVC4156"
+ }
+
+ #-----------SVC4157---------------------------
+ # %1 - "The model name"
+ # %2 - "List of allowed models"
+ VSP_MODEL_NOT_ALLOWED: {
+ code: 400,
+ message: "The Model '%1' is not allowed for the imported Vendor Software Product. Allowed Models: '%2'",
+ messageId: "SVC4157"
+ }
+
+ #---------SVC4158-----------------------------
+ # %1 - Valid artifact label name
+ INVALID_ARTIFACT_LABEL_NAME: {
+ code: 400,
+ message: "Invalid label name. Only the following characters are allowed in label name: '%1'",
+ messageId: "SVC4158"
+ }
+
+ #---------SVC4159-----------------------------
+ # %1 - The model name
+ COULD_NOT_DELETE_MODEL: {
+ code: 500,
+ message: "Could not delete the model '%1'.",
+ messageId: "SVC4159"
+ }
+
+ #---------SVC4160-----------------------------
+ # %1 - The model name
+ COULD_NOT_DELETE_MODEL_ELEMENTS: {
+ code: 500,
+ message: "Could not delete the model '%1' elements.",
+ messageId: "SVC4160"
+ }
+ #---------SVC4161-----------------------------
+ INVALID_NODE_TYPES_YAML: {
+ code: 400,
+ message: "Invalid node_types TOSCA yaml",
+ messageId: "SVC4161"
+ }
+
+ #---------SVC4162-----------------------------
+ # %1 - The janusgraph status
+ FAILED_CREATE_ARTIFACTS_TYPES: {
+ code: 500,
+ message: "Failed to create artifact types with status '%1'.",
+ messageId: "SVC4162"
+ }
+
+ #---------SVC4163-----------------------------
+ # %1 - The janusgraph status
+ ARTIFACT_TYPE_ALREADY_EXIST: {
+ code: 409,
+ message: "Artifact type '%1' already exist.",
+ messageId: "SVC4163"
+ }
+
+ #---------SVC4692-----------------------------
+ # %1 - Component name
+ COMPONENT_NOT_ARCHIVED: {
+ code: 403,
+ message: "Component '%1' is not archived",
+ messageId: "SVC4692"
+ }
+
+ #---------SVC4693-----------------------------
+ # %1 - List of services
+ COMPONENT_IN_USE_BY_ANOTHER_COMPONENT: {
+ code: 403,
+ message: "Component is in use by '%1'",
+ messageId: "SVC4693"
+ }
+
+ #---------SVC4164-----------------------------
+ # %1 - componentType
+ # %2 - component name
+ CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES: {
+ code: 409,
+ message: "System deployed '%1' cannot be deleted '%2'",
+ messageId: "SVC4164"
+ }
+
+ #---------SVC4165-----------------------------
+ # %1 - input origin
+ TOSCA_GET_FUNCTION_INPUTS_ONLY_SELF_ERROR: {
+ code: 400,
+ message: "Invalid get_input definition. Inputs can only be get from SELF, the given origin was '%1'",
+ messageId: "SVC4165"
+ }
+
+ #---------SVC4166-----------------------------
+ # %1 - input name
+ # %2 - input origin
+ TOSCA_GET_FUNCTION_INPUTS_NOT_FOUND: {
+ code: 404,
+ message: "The given input '%1' was not found on '%2'.",
+ messageId: "SVC4166"
+ }
+
+ #---------SVC4167-----------------------------
+ # %1 - Tosca function
+ # %2 - Referred input type
+ # %3 - Selected property type
+ TOSCA_GET_FUNCTION_TYPE_DIVERGE: {
+ code: 400,
+ message: "Could not set %1. Referred input type '%2' diverges from the selected property type '%3'.",
+ messageId: "SVC4167"
+ }
+
+ #---------SVC4168-----------------------------
+ # %1 - Tosca function
+ # %2 - Referred input schema
+ # %3 - Selected property schema
+ TOSCA_GET_FUNCTION_SCHEMA_DIVERGE: {
+ code: 400,
+ message: "Could not set %1. Referred input schema '%2' diverges from the selected property schema '%3'.",
+ messageId: "SVC4168"
+ }
+
+ #---------SVC4169-----------------------------
+ # %1 - Property type (property|input|attribute)
+ # %1 - Property name
+ # %2 - Property origin
+ TOSCA_GET_FUNCTION_PROPERTY_NOT_FOUND: {
+ code: 404,
+ message: "The given %1 '%2' was not found on '%3'.",
+ messageId: "SVC4169"
+ }
+
+ #---------SVC4170-----------------------------
+ # %1 - Property type (property|input|attribute)
+ # %2 - Property name/path
+ # %3 - Property data type
+ TOSCA_GET_FUNCTION_PROPERTY_DATA_TYPE_NOT_FOUND: {
+ code: 404,
+ message: "The %1 '%2' type '%3' was not found.",
+ messageId: "SVC4170"
+ }
+
+ #---------SVC4171-----------------------------
+ # %1 - Instance name
+ TOSCA_GET_FUNCTION_INSTANCE_NOT_FOUND: {
+ code: 404,
+ message: "The instance '%1' was not found.",
+ messageId: "SVC4171"
+ }
+
+ #-----------SVC4172---------------------------
+ #%1 - TOSCA function attribute
+ TOSCA_FUNCTION_MISSING_ATTRIBUTE: {
+ code: 400,
+ message: "Missing TOSCA function '%1'.",
+ messageId: "SVC4172"
+ }
+
+ #-----------SVC4173---------------------------
+ RELATIONSHIP_TEMPLATE_NOT_FOUND: {
+ code: 404,
+ message: "Relationship_templates entry not found in TOSCA CSAR.",
+ messageId: "SVC4173"
+ }
+
+ #-----------SVC4174---------------------------
+ RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND: {
+ code: 404,
+ message: "Relationship_templates definition not found in TOSCA CSAR.",
+ messageId: "SVC4174"
+ }
+
+ #-----------SVC4175---------------------------
+ TOSCA_FUNCTION_EXPECTED_ERROR: {
+ code: 400,
+ message: "Expecting a Tosca Function value.",
+ messageId: "SVC4175"
+ }
+
+ #-----------SVC4176---------------------------
+ FILTER_CONSTRAINT_MISSING: {
+ code: 400,
+ message: "The filter constraint was not provided.",
+ messageId: "SVC4176"
+ }
+
+ #-----------SVC4177---------------------------
+ #%1 - The missing field
+ FILTER_CONSTRAINT_MISSING_FIELD: {
+ code: 400,
+ message: "Required field '%1' is missing in the filter constraint.",
+ messageId: "SVC4177"
+ }
+
+ #%1 - the component id
+ SUBSTITUTION_FILTER_NOT_FOUND: {
+ code: 404,
+ message: 'Substitution filter not found in the component "%1"',
+ messageId: "SVC4178"
+ }
+
+ # %1 - Component name
+ COMPONENT_DOES_NOT_HAVE_INPUTS: {
+ code: 400,
+ message: "Component '%1' does not have inputs.",
+ messageId: "SVC4179"
+ }
+
+ # %1 - Input name
+ # %2 - Component name
+ COMPONENT_INPUT_NOT_FOUND: {
+ code: 400,
+ message: "Input '%1' does not exist in '%2'.",
+ messageId: "SVC4180"
+ }
+
+ # %1 - Target property name
+ # %2 - Source property name
+ SOURCE_TARGET_SCHEMA_MISMATCH: {
+ code: 400,
+ message: "Target property '%1' schema '%2' does not match with source property '%3' schema '%4'.",
+ messageId: "SVC4181"
+ }
+
+ # %1 - Property name
+ # %2 - Component name
+ COMPONENT_PROPERTY_NOT_FOUND:
+ code: 400
+ message: "Property '%1' does not exist in '%2'."
+ messageId: "SVC4183"
+
+ # %1 - The component type
+ # %2 - The expected component types
+ INVALID_COMPONENT_TYPE:
+ code: 400
+ message: "Invalid component type '%1'. Expected types are: %2"
+ messageId: "SVC4185"
+
+ # %1 - The capability name
+ # %2 - The component type
+ # %3 - The component name
+ CAPABILITY_NOT_FOUND_IN_COMPONENT:
+ code: 400
+ message: "Capability '%1' not found in '%2' '%3'."
+ messageId: "SVC4186"
+
+ # %1 - The data type Uid
+ DATA_TYPE_NOT_FOUND:
+ code: 404
+ message: "Data type '%1' was not found."
+ messageId: "SVC4011"
+
+ # %1 - The data type Uid
+ # %2 - The property name
+ DATA_TYPE_PROPERTY_ALREADY_EXISTS:
+ code: 409
+ message: "Data type '%1' property '%2' already exists."
+ messageId: "SVC4012"
+
+ # %1 - The operation that the error occurred
+ UNEXPECTED_ERROR:
+ code: 500
+ message: "An unexpected error occurred while %1."
+ messageId: "SVC4013"
+
diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
index 75f8904519..4be1cbab66 100644
--- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
+++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
@@ -2833,4 +2833,17 @@ errors:
DATA_TYPE_NOT_FOUND:
code: 404
message: "Data type '%1' was not found."
- messageId: "SVC4011" \ No newline at end of file
+ messageId: "SVC4011"
+
+ # %1 - The data type Uid
+ # %2 - The property name
+ DATA_TYPE_PROPERTY_ALREADY_EXISTS:
+ code: 409
+ message: "Data type '%1' property '%2' already exists."
+ messageId: "SVC4012"
+
+ # %1 - The operation that the error occurred
+ UNEXPECTED_ERROR:
+ code: 500
+ message: "An unexpected error occurred while %1."
+ messageId: "SVC4013"
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java
index e39e0d2c0d..711ebcbd9c 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DataTypeServlet.java
@@ -22,9 +22,12 @@ package org.openecomp.sdc.be.servlets;
import com.jcabi.aspects.Loggable;
import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.servers.Server;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -41,6 +44,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
import org.openecomp.sdc.be.config.BeEcompErrorManager;
@@ -114,9 +118,31 @@ public class DataTypeServlet extends BeGenericServlet {
@ApiResponse(responseCode = "403", description = "Restricted operation"),
@ApiResponse(responseCode = "404", description = "Data type not found")})
@PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
- public Response fetchProperties(@PathParam("id") final String id) {
+ public Response fetchProperties(@Parameter(in = ParameterIn.PATH, required = true, description = "The data type id")
+ @PathParam("id") final String id) {
final List<PropertyDefinition> allProperties = dataTypeOperation.findAllProperties(id);
return buildOkResponse(allProperties);
}
+ @POST
+ @Path("{id}/properties")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Operation(summary = "Create a property in the given data type", method = "POST", description = "Create a property in the given data type",
+ responses = {
+ @ApiResponse(content = @Content(schema = @Schema(implementation = PropertyDefinitionDto.class))),
+ @ApiResponse(responseCode = "201", description = "Property created in the data type"),
+ @ApiResponse(responseCode = "400", description = "Invalid payload"),
+ @ApiResponse(responseCode = "409", description = "Property already exists in the data type"),
+ @ApiResponse(responseCode = "403", description = "Restricted operation"),
+ @ApiResponse(responseCode = "404", description = "Data type not found")
+ })
+ @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
+ public Response createProperty(@Parameter(in = ParameterIn.PATH, required = true, description = "The data type id")
+ @PathParam("id") final String id,
+ @RequestBody(description = "Property to add", required = true) final PropertyDefinitionDto propertyDefinitionDto) {
+ final PropertyDefinitionDto property = dataTypeOperation.createProperty(id, propertyDefinitionDto);
+ return Response.status(Status.CREATED).entity(property).build();
+ }
+
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/DefaultExceptionMapper.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/DefaultExceptionMapper.java
index 6b161f9d4e..a2a8659b71 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/DefaultExceptionMapper.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/DefaultExceptionMapper.java
@@ -23,18 +23,19 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.eclipse.jetty.http.HttpStatus;
-import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
@Provider
public class DefaultExceptionMapper implements ExceptionMapper<Exception> {
- private static final Logger log = Logger.getLogger(DefaultExceptionMapper.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExceptionMapper.class);
@Override
- public Response toResponse(Exception exception) {
- log.debug("#toResponse - An error occurred: ", exception);
+ public Response toResponse(final Exception exception) {
+ LOGGER.error("An unhandled error has occurred", exception);
return Response.status(HttpStatus.INTERNAL_SERVER_ERROR_500).entity(exception.getMessage()).build();
}
}
diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml
index 0830dda7b4..ee5f7fa836 100644
--- a/catalog-be/src/main/resources/config/error-configuration.yaml
+++ b/catalog-be/src/main/resources/config/error-configuration.yaml
@@ -2834,3 +2834,17 @@ errors:
code: 404
message: "Data type '%1' was not found."
messageId: "SVC4011"
+
+ # %1 - The data type Uid
+ # %2 - The property name
+ DATA_TYPE_PROPERTY_ALREADY_EXISTS:
+ code: 409
+ message: "Data type '%1' property '%2' already exists."
+ messageId: "SVC4012"
+
+ # %1 - The operation that the error occurred
+ UNEXPECTED_ERROR:
+ code: 500
+ message: "An unexpected error occurred while %1."
+ messageId: "SVC4013"
+
diff --git a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml
index d31d4a6203..ad40131f28 100644
--- a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml
+++ b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml
@@ -2820,4 +2820,24 @@ errors:
CAPABILITY_NOT_FOUND_IN_COMPONENT:
code: 400
message: "Capability '%1' not found in '%2' '%3'."
- messageId: "SVC4186" \ No newline at end of file
+ messageId: "SVC4186"
+
+ # %1 - The data type Uid
+ DATA_TYPE_NOT_FOUND:
+ code: 404
+ message: "Data type '%1' was not found."
+ messageId: "SVC4011"
+
+ # %1 - The data type Uid
+ # %2 - The property name
+ DATA_TYPE_PROPERTY_ALREADY_EXISTS:
+ code: 409
+ message: "Data type '%1' property '%2' already exists."
+ messageId: "SVC4012"
+
+ # %1 - The operation that the error occurred
+ UNEXPECTED_ERROR:
+ code: 500
+ message: "An unexpected error occurred while %1."
+ messageId: "SVC4013"
+
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
index 55297f9e13..cd5a6e5d7a 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
@@ -148,5 +148,7 @@ public enum ActionStatus {
COMPONENT_DOES_NOT_HAVE_INPUTS,
COMPONENT_INPUT_NOT_FOUND,
COMPONENT_PROPERTY_NOT_FOUND,
- INVALID_COMPONENT_TYPE
+ INVALID_COMPONENT_TYPE,
+ DATA_TYPE_PROPERTY_ALREADY_EXISTS,
+ UNEXPECTED_ERROR
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/exception/OperationException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/exception/OperationException.java
deleted file mode 100644
index 6a647b1d44..0000000000
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/exception/OperationException.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * -
- * ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.openecomp.sdc.be.exception;
-
-public class OperationException extends BusinessException {
-
- public OperationException(final String message) {
- super(message);
- }
-
- public OperationException(final Throwable cause) {
- super(cause);
- }
-
- public OperationException(final String message, final Throwable cause) {
- super(message, cause);
- }
-
-}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/exception/supplier/DataTypeOperationExceptionSupplier.java b/catalog-model/src/main/java/org/openecomp/sdc/be/exception/supplier/DataTypeOperationExceptionSupplier.java
index 75cacdd7a8..6b444b26ad 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/exception/supplier/DataTypeOperationExceptionSupplier.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/exception/supplier/DataTypeOperationExceptionSupplier.java
@@ -24,14 +24,28 @@ package org.openecomp.sdc.be.exception.supplier;
import java.util.function.Supplier;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
-import org.openecomp.sdc.be.exception.OperationException;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DataTypeOperationExceptionSupplier {
public static Supplier<OperationException> unexpectedErrorWhileFetchingProperties(final String uniqueId) {
- final String errorMessage = String.format("An unexpected error has occurred while retrieving the data type '%s' properties", uniqueId);
- return () -> new OperationException(errorMessage);
+ return () -> new OperationException(ActionStatus.UNEXPECTED_ERROR, String.format("retrieving the data type '%s' properties", uniqueId));
+ }
+
+ public static Supplier<OperationException> dataTypeNotFound(final String dataTypeId) {
+ return () -> new OperationException(ActionStatus.DATA_TYPE_NOT_FOUND, dataTypeId);
+ }
+
+ public static Supplier<OperationException> dataTypePropertyAlreadyExists(final String dataTypeId, final String propertyName) {
+ return () -> new OperationException(ActionStatus.DATA_TYPE_PROPERTY_ALREADY_EXISTS, dataTypeId, propertyName);
+ }
+
+ public static Supplier<OperationException> unexpectedErrorWhileCreatingProperty(String dataTypeId, String propertyName) {
+ return () -> new OperationException(ActionStatus.UNEXPECTED_ERROR,
+ String.format("creating the property '%s' in the data type '%s'", propertyName, dataTypeId)
+ );
}
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/PropertyDefinitionDto.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/PropertyDefinitionDto.java
index bac73d9e1d..4144e1f5b6 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/PropertyDefinitionDto.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/PropertyDefinitionDto.java
@@ -30,7 +30,9 @@ public class PropertyDefinitionDto {
private String uniqueId;
private String type;
+ private String schemaType;
private String name;
+ private String description;
private Boolean required;
private Object value;
private Object defaultValue;
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/mapper/PropertyDefinitionDtoMapper.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/mapper/PropertyDefinitionDtoMapper.java
index 8566f55339..67600a5dbe 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/mapper/PropertyDefinitionDtoMapper.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/mapper/PropertyDefinitionDtoMapper.java
@@ -24,12 +24,17 @@ package org.openecomp.sdc.be.model.mapper;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
import org.openecomp.sdc.be.model.PropertyConstraint;
import org.openecomp.sdc.be.model.PropertyDefinition;
import org.openecomp.sdc.be.model.dto.PropertyDefinitionDto;
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PropertyDefinitionDtoMapper {
public static PropertyDefinition mapTo(final PropertyDefinitionDto propertyDefinitionDto) {
@@ -38,11 +43,19 @@ public class PropertyDefinitionDtoMapper {
propertyDefinition.setType(propertyDefinitionDto.getType());
propertyDefinition.setRequired(propertyDefinitionDto.getRequired());
propertyDefinition.setName(propertyDefinitionDto.getName());
+ if (StringUtils.isNotBlank(propertyDefinitionDto.getSchemaType())) {
+ final PropertyDefinition schemaProperty = new PropertyDefinition();
+ schemaProperty.setType(propertyDefinitionDto.getSchemaType());
+ final SchemaDefinition schema = new SchemaDefinition();
+ schema.setProperty(schemaProperty);
+ propertyDefinition.setSchema(schema);
+ }
if (CollectionUtils.isNotEmpty(propertyDefinitionDto.getConstraints())) {
final List<PropertyConstraint> propertyConstraints = new ArrayList<>();
propertyDefinition.setConstraints(propertyConstraints);
propertyConstraints.addAll(propertyDefinitionDto.getConstraints());
}
+ propertyDefinition.setDescription(propertyDefinitionDto.getDescription());
propertyDefinition.setValue(new Gson().toJson(propertyDefinitionDto.getValue()));
propertyDefinition.setDefaultValue(new Gson().toJson(propertyDefinitionDto.getDefaultValue()));
return propertyDefinition;
@@ -52,9 +65,11 @@ public class PropertyDefinitionDtoMapper {
final var propertyDefinition = new PropertyDefinition(propertyDataDefinition);
final var propertyDefinitionDto = new PropertyDefinitionDto();
propertyDefinitionDto.setUniqueId(propertyDefinition.getUniqueId());
+ propertyDefinitionDto.setName(propertyDefinition.getName());
propertyDefinitionDto.setType(propertyDefinition.getType());
+ propertyDefinitionDto.setDescription(propertyDefinition.getDescription());
propertyDefinitionDto.setRequired(propertyDefinition.getRequired());
- propertyDefinitionDto.setName(propertyDefinition.getName());
+ propertyDefinitionDto.setSchemaType(propertyDefinition.getSchemaType());
if (CollectionUtils.isNotEmpty(propertyDefinition.getConstraints())) {
final List<PropertyConstraint> propertyConstraints = new ArrayList<>();
propertyDefinitionDto.setConstraints(propertyConstraints);
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java
index 4194ab70db..7cd042a27d 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperation.java
@@ -39,12 +39,16 @@ import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
import org.openecomp.sdc.be.exception.supplier.DataTypeOperationExceptionSupplier;
import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.dto.PropertyDefinitionDto;
import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
+import org.openecomp.sdc.be.model.mapper.PropertyDefinitionDtoMapper;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.resources.data.DataTypeData;
+import org.openecomp.sdc.be.resources.data.PropertyData;
import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -204,4 +208,29 @@ public class DataTypeOperation extends AbstractOperation {
return propertyDefinitions;
}
+ public PropertyDefinitionDto createProperty(final String dataTypeId, final PropertyDefinitionDto propertyDefinitionDto) {
+ final String propertyName = propertyDefinitionDto.getName();
+ LOGGER.debug("Adding property '{}' to data type '{}'.", propertyName, dataTypeId);
+
+ getDataTypeByUid(dataTypeId).orElseThrow(DataTypeOperationExceptionSupplier.dataTypeNotFound(dataTypeId));
+
+ final Either<PropertyData, JanusGraphOperationStatus> resultEither =
+ propertyOperation.addPropertyToNodeType(propertyName, PropertyDefinitionDtoMapper.mapTo(propertyDefinitionDto),
+ NodeTypeEnum.DataType, dataTypeId, false);
+ if (resultEither.isRight()) {
+ final JanusGraphOperationStatus status = resultEither.right().value();
+ LOGGER.debug("Could not create property '{}' on data type '{}'. JanusGraph status is '{}'", propertyName, dataTypeId, status);
+ if (status == JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION) {
+ throw DataTypeOperationExceptionSupplier.dataTypePropertyAlreadyExists(dataTypeId, propertyName).get();
+ }
+ LOGGER.error("Could not create property '{}' on data type '{}'. JanusGraph status is '{}'", propertyName, dataTypeId, status);
+ throw DataTypeOperationExceptionSupplier.unexpectedErrorWhileCreatingProperty(dataTypeId, propertyName).get();
+ }
+ LOGGER.debug("Property '{}' was added to data type '{}'.", propertyName, dataTypeId);
+ final PropertyData propertyData = resultEither.left().value();
+ final PropertyDataDefinition propertyDataDefinition = propertyData.getPropertyDataDefinition();
+ propertyDataDefinition.setName(propertyName);
+ return PropertyDefinitionDtoMapper.mapFrom(propertyDataDefinition);
+ }
+
}
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
index 1068e31db6..cd87dd4fe7 100644
--- 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
@@ -332,6 +332,13 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe
public Either<PropertyData, JanusGraphOperationStatus> addPropertyToNodeType(String propertyName, PropertyDefinition propertyDefinition,
NodeTypeEnum nodeType, String uniqueId) {
+ return addPropertyToNodeType(propertyName, propertyDefinition, nodeType, uniqueId, true);
+ }
+
+ public Either<PropertyData, JanusGraphOperationStatus> addPropertyToNodeType(final String propertyName,
+ final PropertyDefinition propertyDefinition,
+ final NodeTypeEnum nodeType, final String uniqueId,
+ final boolean inTransaction) {
List<PropertyConstraint> constraints = propertyDefinition.getConstraints();
propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName));
PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints));
@@ -339,6 +346,9 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe
Either<PropertyData, JanusGraphOperationStatus> createNodeResult = janusGraphGenericDao.createNode(propertyData, PropertyData.class);
log.debug(AFTER_ADDING_PROPERTY_TO_GRAPH, propertyData);
if (createNodeResult.isRight()) {
+ if (!inTransaction) {
+ janusGraphGenericDao.rollback();
+ }
JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus);
return Either.right(operationStatus);
@@ -350,10 +360,16 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe
Either<GraphRelation, JanusGraphOperationStatus> createRelResult =
janusGraphGenericDao.createRelation(uniqueIdData, propertyData, GraphEdgeLabels.PROPERTY, props);
if (createRelResult.isRight()) {
+ if (!inTransaction) {
+ janusGraphGenericDao.rollback();
+ }
JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
log.error(FAILED_TO_ASSOCIATE_RESOURCE_TO_PROPERTY_IN_GRAPH_STATUS_IS, uniqueId, propertyName, operationStatus);
return Either.right(operationStatus);
}
+ if (!inTransaction) {
+ janusGraphGenericDao.commit();
+ }
return Either.left(createNodeResult.left().value());
}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java
index 1f448fd875..26fb7658f1 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/DataTypeOperationTest.java
@@ -19,7 +19,9 @@
package org.openecomp.sdc.be.model.operations.impl;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -42,14 +44,18 @@ import org.mockito.MockitoAnnotations;
import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao;
import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
-import org.openecomp.sdc.be.exception.OperationException;
import org.openecomp.sdc.be.exception.supplier.DataTypeOperationExceptionSupplier;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.Model;
import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.dto.PropertyDefinitionDto;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
+import org.openecomp.sdc.be.model.mapper.PropertyDefinitionDtoMapper;
import org.openecomp.sdc.be.resources.data.DataTypeData;
+import org.openecomp.sdc.be.resources.data.PropertyData;
import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration("classpath:application-context-test.xml")
@@ -87,9 +93,10 @@ class DataTypeOperationTest {
when(janusGraphGenericDao.getByCriteriaForModel(NodeTypeEnum.DataType, null, modelName, DataTypeData.class))
.thenReturn(Either.left(dataTypesWithModel));
final var dataTypesFound = dataTypeOperation.getAllDataTypeNodes();
- assertThat(dataTypesFound.size()).isEqualTo(4);
- assertThat(dataTypesFound.containsAll(dataTypesWithoutModel)).isTrue();
- assertThat(dataTypesFound.containsAll(dataTypesWithModel)).isTrue();
+ assertThat(dataTypesFound)
+ .hasSize(4)
+ .containsAll(dataTypesWithoutModel)
+ .containsAll(dataTypesWithModel);
}
@Test
@@ -100,8 +107,9 @@ class DataTypeOperationTest {
when(janusGraphGenericDao.getByCriteriaForModel(NodeTypeEnum.DataType, null, modelName, DataTypeData.class))
.thenReturn(Either.left(dataTypesWithModel));
final var dataTypesFound = dataTypeOperation.getAllDataTypeNodes();
- assertThat(dataTypesFound.size()).isEqualTo(2);
- assertThat(dataTypesFound.containsAll(dataTypesWithModel)).isTrue();
+ assertThat(dataTypesFound)
+ .hasSize(2)
+ .containsAll(dataTypesWithModel);
assertThat(dataTypesFound.containsAll(dataTypesWithoutModel)).isFalse();
}
@@ -110,7 +118,7 @@ class DataTypeOperationTest {
when(janusGraphGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class))
.thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
final var dataTypesFound = dataTypeOperation.getAllDataTypeNodes();
- assertThat(dataTypesFound.isEmpty()).isTrue();
+ assertThat(dataTypesFound).isEmpty();
}
@Test
@@ -187,6 +195,79 @@ class DataTypeOperationTest {
assertEquals(expectedException.getMessage(), actualException.getMessage());
}
+ @Test
+ void createPropertyTest_Success() {
+ final String dataTypeId = "uniqueId";
+ final var property1 = new PropertyDefinitionDto();
+ property1.setName("property1");
+ final var propertyData = new PropertyData();
+ final var propertyDataDefinition = new PropertyDataDefinition();
+ propertyDataDefinition.setName("property1");
+ propertyData.setPropertyDataDefinition(propertyDataDefinition);
+ when(janusGraphGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), dataTypeId, DataTypeData.class))
+ .thenReturn(Either.left(new DataTypeData()));
+ when(propertyOperation.addPropertyToNodeType(eq(property1.getName()), any(PropertyDefinition.class),
+ eq(NodeTypeEnum.DataType), eq(dataTypeId), eq(false)))
+ .thenReturn(Either.left(propertyData));
+ final PropertyDefinitionDto propertyDefinitionDto = dataTypeOperation.createProperty(dataTypeId, property1);
+ assertNotNull(propertyDefinitionDto);
+ assertEquals(property1.getName(), propertyDefinitionDto.getName());
+ }
+
+ @Test
+ void createPropertyTest_DataTypePropertyAlreadyExists() {
+ final String dataTypeId = "uniqueId";
+ final var property1 = new PropertyDefinitionDto();
+ property1.setName("property1");
+ when(janusGraphGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), dataTypeId, DataTypeData.class))
+ .thenReturn(Either.left(new DataTypeData()));
+ when(propertyOperation.addPropertyToNodeType(eq(property1.getName()), any(PropertyDefinition.class),
+ eq(NodeTypeEnum.DataType), eq(dataTypeId), eq(false)))
+ .thenReturn(Either.right(JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION));
+ final OperationException actualException = assertThrows(OperationException.class,
+ () -> dataTypeOperation.createProperty(dataTypeId, property1));
+ final OperationException expectedException =
+ DataTypeOperationExceptionSupplier.dataTypePropertyAlreadyExists(dataTypeId, property1.getName()).get();
+
+ assertEquals(expectedException.getActionStatus(), actualException.getActionStatus());
+ assertArrayEquals(expectedException.getParams(), actualException.getParams());
+ }
+
+ @Test
+ void createPropertyTest_DataTypeNotFound() {
+ final String dataTypeId = "uniqueId";
+ final var property1 = new PropertyDefinitionDto();
+ property1.setName("property1");
+ when(janusGraphGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), dataTypeId, DataTypeData.class))
+ .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
+ final OperationException actualException = assertThrows(OperationException.class,
+ () -> dataTypeOperation.createProperty(dataTypeId, property1));
+ final OperationException expectedException =
+ DataTypeOperationExceptionSupplier.dataTypeNotFound(dataTypeId).get();
+
+ assertEquals(expectedException.getActionStatus(), actualException.getActionStatus());
+ assertArrayEquals(expectedException.getParams(), actualException.getParams());
+ }
+
+ @Test
+ void createPropertyTest_UnexpectedError() {
+ final String dataTypeId = "uniqueId";
+ final var property1 = new PropertyDefinitionDto();
+ property1.setName("property1");
+ when(janusGraphGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), dataTypeId, DataTypeData.class))
+ .thenReturn(Either.left(new DataTypeData()));
+ when(propertyOperation.addPropertyToNodeType(eq(property1.getName()), any(PropertyDefinition.class),
+ eq(NodeTypeEnum.DataType), eq(dataTypeId), eq(false)))
+ .thenReturn(Either.right(JanusGraphOperationStatus.GENERAL_ERROR));
+ final OperationException actualException = assertThrows(OperationException.class,
+ () -> dataTypeOperation.createProperty(dataTypeId, property1));
+ final OperationException expectedException =
+ DataTypeOperationExceptionSupplier.unexpectedErrorWhileCreatingProperty(dataTypeId, property1.getName()).get();
+
+ assertEquals(expectedException.getActionStatus(), actualException.getActionStatus());
+ assertArrayEquals(expectedException.getParams(), actualException.getParams());
+ }
+
private void initTestData() {
model = new Model(modelName, ModelTypeEnum.NORMATIVE);
final String TEST_DATA_TYPE_001 = "test.data.type001";
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html
index 1e0804eb04..6a5bd5a007 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.html
@@ -67,12 +67,16 @@
<ul *ngIf="isExpanded">
<li class="input-value">
<ng-container *ngIf="isViewOnly">
- {{valueObjRef}}<em class="empty-value" *ngIf="valueObjRef !== false && !valueObjRef">empty</em>
+ {{valueObjRef}}<em class="empty-value" *ngIf="valueObjRef !== false && !valueObjRef">{{'GENERAL_LABEL_EMPTY' | translate | lowercase}}</em>
</ng-container>
- <input *ngIf="!isViewOnly" [type]="getSimpleValueInputType()" name="value"
- [(ngModel)]="valueObjRef"
- (ngModelChange)="onValueChange($event)"
- />
+ <input *ngIf="!isViewOnly && isTypeLiteral(type.name)" type="text" name="value"
+ [(ngModel)]="valueObjRef" (ngModelChange)="onValueChange($event)"/>
+ <input *ngIf="!isViewOnly && isTypeNumber(type.name)" type="number"
+ [(ngModel)]="valueObjRef" (ngModelChange)="onValueChange($event)"/>
+ <select *ngIf="!isViewOnly && isTypeBoolean(type.name)" [(ngModel)]="valueObjRef" (ngModelChange)="onValueChange($event)">
+ <option [value]="true">{{'GENERAL_LABEL_TRUE' | translate}}</option>
+ <option [value]="false">{{'GENERAL_LABEL_FALSE' | translate}}</option>
+ </select>
</li>
</ul>
</ng-container>
@@ -123,7 +127,7 @@
[type]="getDataType(schema.property.type)"
[dataTypeMap]="dataTypeMap"
[valueObjRef]="valueObjRef[i]"
- [schema]="schema"
+ [schema]="buildSchemaGroupProperty()"
[nestingLevel]="nestingLevel + 1"
[listIndex]="i"
[isListChild]="true"
@@ -155,7 +159,7 @@
[type]="getDataType(schema.property.type)"
[dataTypeMap]="dataTypeMap"
[valueObjRef]="valueObjRef[key]"
- [schema]="schema"
+ [schema]="buildSchemaGroupProperty()"
[isMapChild]="true"
[nestingLevel]="nestingLevel + 1"
[isViewOnly]="isViewOnly"
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts
index 88ff8deec6..145aad687c 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-list/input-list-item/input-list-item.component.ts
@@ -21,12 +21,13 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {DataTypeModel} from '../../../../../../../models/data-types';
-import {SchemaPropertyGroupModel} from '../../../../../../../models/schema-property';
-import {DerivedPropertyType, PropertyBEModel} from '../../../../../../../models/properties-inputs/property-be-model';
+import {SchemaProperty, SchemaPropertyGroupModel} from '../../../../../../../models/schema-property';
+import {PropertyBEModel} from '../../../../../../../models/properties-inputs/property-be-model';
import {PROPERTY_DATA, PROPERTY_TYPES} from '../../../../../../../utils/constants';
import {ToscaFunction} from '../../../../../../../models/tosca-function';
-import {ToscaFunctionValidationEvent} from "../../../../../../../ng2/pages/properties-assignment/tosca-function/tosca-function.component";
+import {ToscaFunctionValidationEvent} from "../../../../../properties-assignment/tosca-function/tosca-function.component";
import {InstanceFeDetails} from "../../../../../../../models/instance-fe-details";
+import {ToscaTypeHelper} from "app/utils/tosca-type-helper";
@Component({
selector: 'app-input-list-item',
@@ -41,6 +42,7 @@ export class InputListItemComponent implements OnInit {
@Input() type: DataTypeModel;
@Input() schema: SchemaPropertyGroupModel;
@Input() nestingLevel: number;
+ @Input() isExpanded: boolean = false;
@Input() isListChild: boolean = false;
@Input() isMapChild: boolean = false;
@Input() showToscaFunctionOption: boolean = false;
@@ -53,12 +55,11 @@ export class InputListItemComponent implements OnInit {
@Output('onDelete') onDeleteEvent: EventEmitter<string> = new EventEmitter<string>();
@Output('onChildListItemDelete') onChildListItemDeleteEvent: EventEmitter<number> = new EventEmitter<number>();
- isExpanded: boolean = false;
mapEntryName: string;
isToscaFunction: boolean = false;
property: PropertyBEModel;
- ngOnInit() {
+ ngOnInit(): void {
if (!this.nestingLevel) {
this.nestingLevel = 0;
}
@@ -93,26 +94,20 @@ export class InputListItemComponent implements OnInit {
}
}
- getType(typeName: string): DerivedPropertyType {
- if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(typeName) > -1) {
- return DerivedPropertyType.SIMPLE;
- } else if (typeName === PROPERTY_TYPES.LIST) {
- return DerivedPropertyType.LIST;
- } else if (typeName === PROPERTY_TYPES.MAP) {
- return DerivedPropertyType.MAP;
- } else if (typeName === PROPERTY_TYPES.RANGE) {
- return DerivedPropertyType.RANGE;
- } else {
- return DerivedPropertyType.COMPLEX;
- }
+ isTypeSimple(typeName: string): boolean {
+ return ToscaTypeHelper.isTypeSimple(typeName) || this.isTypeDerivedFromSimple(typeName) && (this.isTypeWithoutProperties(typeName));
+ }
+
+ isTypeRange(typeName: string): boolean {
+ return ToscaTypeHelper.isTypeRange(typeName);
}
isTypeWithoutProperties(typeName: string): boolean {
- if (this.dataTypeMap.get(typeName) === undefined) {
- return true;
- }
- return this.dataTypeMap.get(typeName).properties === undefined ||
- this.dataTypeMap.get(typeName).properties.length == 0;
+ if (this.dataTypeMap.get(typeName) === undefined) {
+ return true;
+ }
+ return this.dataTypeMap.get(typeName).properties === undefined ||
+ this.dataTypeMap.get(typeName).properties.length == 0;
}
isTypeDerivedFromSimple(typeName: string): boolean {
@@ -134,27 +129,28 @@ export class InputListItemComponent implements OnInit {
return true;
}
- isTypeSimple(typeName: string): boolean {
- if (this.getType(typeName) == DerivedPropertyType.SIMPLE) {
- return true;
- }
- return this.isTypeDerivedFromSimple(typeName) && (this.isTypeWithoutProperties(typeName));
+ isTypeList(typeName: string): boolean {
+ return ToscaTypeHelper.isTypeList(typeName);
}
- isTypeRange(typeName: string): boolean {
- return this.getType(typeName) == DerivedPropertyType.RANGE;
+ isTypeMap(typeName: string): boolean {
+ return ToscaTypeHelper.isTypeMap(typeName);
}
- isTypeList(typeName: string): boolean {
- return this.getType(typeName) == DerivedPropertyType.LIST;
+ isTypeComplex(typeName: string): boolean {
+ return ToscaTypeHelper.isTypeComplex(typeName);
}
- isTypeMap(typeName: string): boolean {
- return this.getType(typeName) == DerivedPropertyType.MAP;
+ isTypeNumber(type: string): boolean {
+ return ToscaTypeHelper.isTypeNumber(type);
}
- isTypeComplex(typeName: string): boolean {
- return !this.isTypeSimple(typeName) && !this.isTypeList(typeName) && !this.isTypeMap(typeName) && !this.isTypeRange(typeName);
+ isTypeBoolean(type: string): boolean {
+ return ToscaTypeHelper.isTypeBoolean(type);
+ }
+
+ isTypeLiteral(type: string): boolean {
+ return ToscaTypeHelper.isTypeLiteral(type);
}
expandAndCollapse() {
@@ -180,7 +176,7 @@ export class InputListItemComponent implements OnInit {
}
onValueChange(value: any): void {
- if (this.isNumber(this.type.name)) {
+ if (this.isTypeNumber(this.type.name)) {
this.emitValueChangeEvent(this.parseNumber(value));
return;
}
@@ -297,14 +293,20 @@ export class InputListItemComponent implements OnInit {
}
getSimpleValueInputType() {
- if (this.isNumber(this.type.name)){
+ if (this.isTypeNumber(this.type.name)){
return 'number';
}
return 'text';
}
- isNumber(type: string): boolean {
- return type === PROPERTY_TYPES.INTEGER || type === PROPERTY_TYPES.FLOAT;
+ buildSchemaGroupProperty(): SchemaPropertyGroupModel {
+ const schemaProperty = new SchemaProperty();
+ if (this.schema.property.type === PROPERTY_TYPES.MAP || this.schema.property.type === PROPERTY_TYPES.LIST) {
+ schemaProperty.type = PROPERTY_TYPES.STRING;
+ } else {
+ schemaProperty.type = this.schema.property.type
+ }
+ return new SchemaPropertyGroupModel(schemaProperty);
}
private parseBoolean(value: any) {
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts
index c829ff9e5a..b4fc9d1bdb 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts
@@ -36,31 +36,32 @@ import {PropertyTableModule} from "app/ng2/components/logic/properties-table/pro
import {ToscaFunctionModule} from '../../../properties-assignment/tosca-function/tosca-function.module';
@NgModule({
- declarations: [
- InterfaceOperationHandlerComponent,
- PropertyParamRowComponent,
- AddInputComponent,
- InputListComponent,
- InputListItemComponent
- ],
- imports: [
- CommonModule,
- SdcUiComponentsModule,
- FormsModule,
- FormElementsModule,
- TranslateModule,
- UiElementsModule,
- PropertyTableModule,
- ReactiveFormsModule,
- ToscaFunctionModule
- ],
- exports: [
- PropertyParamRowComponent
- ],
- entryComponents: [
- InterfaceOperationHandlerComponent
- ],
- providers: []
+ declarations: [
+ InterfaceOperationHandlerComponent,
+ PropertyParamRowComponent,
+ AddInputComponent,
+ InputListComponent,
+ InputListItemComponent
+ ],
+ imports: [
+ CommonModule,
+ SdcUiComponentsModule,
+ FormsModule,
+ FormElementsModule,
+ TranslateModule,
+ UiElementsModule,
+ PropertyTableModule,
+ ReactiveFormsModule,
+ ToscaFunctionModule
+ ],
+ exports: [
+ PropertyParamRowComponent,
+ InputListItemComponent
+ ],
+ entryComponents: [
+ InterfaceOperationHandlerComponent
+ ],
+ providers: []
})
export class InterfaceOperationHandlerModule {
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.html b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.html
new file mode 100644
index 0000000000..af72e6d6d6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.html
@@ -0,0 +1,66 @@
+<div class="add-property-container">
+ <loader [display]="isLoading" [size]="'large'" [relative]="true" [loaderDelay]="500"></loader>
+ <form class="w-sdc-form" [formGroup]="formGroup">
+
+ <div class="side-by-side">
+ <div class="i-sdc-form-item">
+ <label class="i-sdc-form-label required">{{'PROPERTY_NAME_LABEL' | translate}}</label>
+ <input class="i-sdc-form-input"
+ type="text"
+ data-tests-id="property-name"
+ formControlName="name"
+ [readOnly]="readOnly"/>
+ </div>
+ <div class="i-sdc-form-item">
+ <label class="i-sdc-form-label required">{{'PROPERTY_TYPE_LABEL' | translate}}</label>
+ <select formControlName="type" (change)="onTypeChange()" [attr.disabled]="readOnly ? readOnly : null">
+ <option [ngValue]="null">{{'GENERAL_LABEL_SELECT' | translate}}</option>
+ <option *ngFor="let type of typeList"
+ [ngValue]="type">{{type}}</option>
+ </select>
+ </div>
+ <div class="i-sdc-form-item">
+ <input type="checkbox" formControlName="required" [attr.disabled]="readOnly ? readOnly : null"/> {{'PROPERTY_REQUIRED_LABEL' | translate}}
+ </div>
+ <div class="i-sdc-form-item propertySchemaType" *ngIf="showSchema">
+ <label class="i-sdc-form-label required">{{'PROPERTY_SCHEMA_LABEL' | translate}}</label>
+ <select formControlName="schema" (change)="onSchemaChange()" [attr.disabled]="readOnly ? readOnly : null">
+ <option [ngValue]="null">{{'GENERAL_LABEL_SELECT' | translate}}</option>
+ <option *ngFor="let type of schemaTypeList"
+ [ngValue]="type">{{type}}</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="i-sdc-form-item">
+ <label class="i-sdc-form-label">{{'PROPERTY_DESCRIPTION_LABEL' | translate}}</label>
+ <textarea class="i-sdc-form-textarea"
+ formControlName="description"
+ data-tests-id="property-description"
+ [readOnly]="readOnly">
+ </textarea>
+ </div>
+ <div class="default-value-container i-sdc-form-item" *ngIf="showDefaultValue()">
+ <label class="i-sdc-form-label">{{'PROPERTY_DEFAULT_VALUE_LABEL' | translate}}</label>
+ <ng-container *ngIf="!readOnly">
+ <input type="checkbox" formControlName="hasDefaultValue" [attr.disabled]="readOnly ? readOnly : null"/> {{'PROPERTY_SET_DEFAULT_VALUE_MSG' | translate}}
+ </ng-container>
+ <ng-container *ngIf="hasDefaultValueForm.value">
+ <ul>
+ <app-input-list-item
+ [name]="nameForm.value"
+ [type]="getDataType(typeForm.value)"
+ [dataTypeMap]="dataTypeMap"
+ [valueObjRef]="defaultValueForm.value"
+ [schema]="buildSchemaGroupProperty()"
+ [nestingLevel]="0"
+ [isViewOnly]="readOnly"
+ [allowDeletion]="false"
+ [isExpanded]="true"
+ (onValueChange)="onPropertyValueChange($event)">
+ </app-input-list-item>
+ </ul>
+ </ng-container>
+ </div>
+ </form>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.less b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.less
new file mode 100644
index 0000000000..2c3300237c
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.less
@@ -0,0 +1,104 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+.add-property-container {
+ max-width: 100%;
+}
+
+.default-value-container {
+ overflow: scroll;
+ max-height: 300px;
+ max-width: 100%;
+
+ ul {
+ margin: 0 0 0 20px;
+ list-style: none;
+ line-height: 2em;
+ }
+
+ &::-webkit-scrollbar-track {
+ border: 0;
+ }
+}
+
+li {
+ position: relative;
+
+ &:before {
+ position: absolute;
+ left: -15px;
+ top: 0;
+ content: '';
+ display: block;
+ border-left: 1px solid #ddd;
+ height: 1em;
+ border-bottom: 1px solid #ddd;
+ width: 10px;
+ }
+
+ &:after {
+ position: absolute;
+ left: -15px;
+ bottom: -7px;
+ content: '';
+ display: block;
+ border-left: 1px solid #ddd;
+ height: 100%;
+ }
+
+ &.root {
+ margin: 0 0 0 -20px;
+
+ &:before {
+ display: none;
+ }
+
+ &:after {
+ display: none;
+ }
+ }
+
+ &:last-child {
+ &:after {
+ display: none
+ }
+ }
+}
+
+.input-label {
+ margin: 0;
+ font-weight: bold;
+}
+
+.input-value {
+ display: flex;
+ flex-flow: row nowrap;
+ gap: 7px;
+
+ input {
+ min-width: 150px;
+ max-width: 250px;
+ }
+}
+
+.empty-value {
+ color: #aaaaaa;
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.spec.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.spec.ts
new file mode 100644
index 0000000000..7e2c312792
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.spec.ts
@@ -0,0 +1,88 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {AddPropertyComponent} from './add-property.component';
+import {FormsModule, ReactiveFormsModule} from "@angular/forms";
+import {TranslateModule} from "../../../../shared/translator/translate.module";
+import {UiElementsModule} from "../../../../components/ui/ui-elements.module";
+import {Component, Input} from "@angular/core";
+import {DataTypeModel} from "../../../../../models/data-types";
+import {SchemaPropertyGroupModel} from "../../../../../models/schema-property";
+import {DataTypeService} from "../../../../services/data-type.service";
+import {TranslateService} from "../../../../shared/translator/translate.service";
+
+@Component({selector: 'app-input-list-item', template: ''})
+class InputListItemStubComponent {
+ @Input() valueObjRef: any;
+ @Input() name: string;
+ @Input() dataTypeMap: Map<string, DataTypeModel>;
+ @Input() type: DataTypeModel;
+ @Input() schema: SchemaPropertyGroupModel;
+ @Input() nestingLevel: number;
+ @Input() isExpanded: boolean = false;
+ @Input() isListChild: boolean = false;
+ @Input() isMapChild: boolean = false;
+ @Input() listIndex: number;
+ @Input() isViewOnly: boolean;
+ @Input() allowDeletion: boolean = false;
+}
+
+describe('AddPropertyComponent', () => {
+ let dataTypeServiceMock: Partial<DataTypeService> = {
+ findAllDataTypesByModel: jest.fn(args => {
+ return Promise.resolve(new Map());
+ })
+ };
+ let translateServiceMock: Partial<TranslateService> = {
+ translate: jest.fn((str: string) => {})
+ };
+ let component: AddPropertyComponent;
+ let fixture: ComponentFixture<AddPropertyComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [AddPropertyComponent, InputListItemStubComponent],
+ imports: [
+ FormsModule,
+ ReactiveFormsModule,
+ TranslateModule,
+ UiElementsModule
+ ],
+ providers: [
+ {provide: DataTypeService, useValue: dataTypeServiceMock},
+ {provide: TranslateService, useValue: translateServiceMock}
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AddPropertyComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.ts
new file mode 100644
index 0000000000..dc1a0329ed
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/add-property/add-property.component.ts
@@ -0,0 +1,233 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
+import {PropertyBEModel} from "../../../../../models/properties-inputs/property-be-model";
+import {AbstractControl, FormControl, FormGroup, ValidationErrors, Validators} from "@angular/forms";
+import {PROPERTY_DATA} from "../../../../../utils/constants";
+import {DataTypeService} from "../../../../services/data-type.service";
+import {DataTypeModel} from "../../../../../models/data-types";
+import {Subscription} from "rxjs";
+import {ToscaTypeHelper} from "../../../../../utils/tosca-type-helper";
+import {SchemaProperty, SchemaPropertyGroupModel} from "../../../../../models/schema-property";
+
+@Component({
+ selector: 'app-add-property',
+ templateUrl: './add-property.component.html',
+ styleUrls: ['./add-property.component.less']
+})
+export class AddPropertyComponent implements OnInit, OnDestroy {
+
+ @Input() property: PropertyBEModel;
+ @Input() readOnly: boolean = true;
+ @Input() model: string;
+
+ @Output() onValidityChange: EventEmitter<PropertyValidationEvent> = new EventEmitter<PropertyValidationEvent>();
+
+ private valueChangesSub: Subscription;
+ private descriptionForm: FormControl = new FormControl(undefined);
+ private requiredForm: FormControl = new FormControl(false, Validators.required);
+ nameForm: FormControl = new FormControl(undefined, [Validators.required]);
+ typeForm: FormControl = new FormControl(undefined, Validators.required);
+ schemaForm: FormControl = new FormControl(undefined, (control: AbstractControl): ValidationErrors | null => {
+ if (this.typeNeedsSchema() && !control.value) {
+ return {required: true};
+ }
+ return null;
+ });
+ hasDefaultValueForm: FormControl = new FormControl(false, Validators.required);
+ defaultValueForm: FormControl = new FormControl(undefined);
+ formGroup: FormGroup = new FormGroup({
+ 'name': this.nameForm,
+ 'description': this.descriptionForm,
+ 'type': this.typeForm,
+ 'required': this.requiredForm,
+ 'schema': this.schemaForm,
+ 'defaultValue': this.defaultValueForm,
+ 'hasDefaultValue': this.hasDefaultValueForm,
+ });
+
+ isLoading: boolean = false;
+ showSchema: boolean = false;
+ typeList: string[];
+ dataTypeMap: Map<string, DataTypeModel>;
+ dataType: DataTypeModel;
+ schemaTypeList: string[];
+
+ constructor(private dataTypeService: DataTypeService) {
+ }
+
+ ngOnInit(): void {
+ this.isLoading = true;
+ this.initTypeAndSchemaDropdown().then(() => this.updateDataType());
+ this.initForm();
+ this.valueChangesSub = this.formGroup.valueChanges.subscribe(() => {
+ this.emitValidityChange();
+ });
+ }
+
+ ngOnDestroy(): void {
+ if (this.valueChangesSub) {
+ this.valueChangesSub.unsubscribe();
+ }
+ }
+
+ onSchemaChange(): void {
+ this.resetDefaultValue();
+ }
+
+ onTypeChange(): void {
+ this.schemaForm.setValue(null);
+ this.showSchema = this.typeNeedsSchema();
+ this.updateDataType();
+ this.resetDefaultValue();
+ }
+
+ private updateDataType(): void {
+ this.dataType = this.dataTypeMap.get(this.typeForm.value);
+ }
+
+ private initForm(): void {
+ if (!this.property) {
+ return;
+ }
+
+ this.nameForm.setValue(this.property.name);
+ this.descriptionForm.setValue(this.property.description);
+ this.typeForm.setValue(this.property.type);
+ this.showSchema = this.typeNeedsSchema();
+ this.requiredForm.setValue(this.property.required);
+ this.schemaForm.setValue(this.property.schemaType);
+ this.initDefaultValueForm();
+ }
+
+ private initDefaultValueForm() {
+ if (this.property.defaultValue == undefined) {
+ return;
+ }
+ let defaultValue;
+ if (!this.isTypeSimple() && typeof this.property.defaultValue === 'string') {
+ defaultValue = JSON.parse(this.property.defaultValue);
+ } else {
+ defaultValue = this.property.defaultValue;
+ }
+ this.defaultValueForm.setValue(defaultValue);
+ this.hasDefaultValueForm.setValue(true);
+ }
+
+ private typeNeedsSchema() {
+ return PROPERTY_DATA.SCHEMA_TYPES.indexOf(this.typeForm.value) > -1;
+ }
+
+ private initTypeAndSchemaDropdown(): Promise<Map<string, DataTypeModel>> {
+ const primitiveTypes: string[] = Array.from(PROPERTY_DATA.TYPES).sort((a, b) => a.localeCompare(b));
+ const promise = this.dataTypeService.findAllDataTypesByModel(this.model);
+ promise.then((dataTypeMap: Map<string, DataTypeModel>) => {
+ this.dataTypeMap = dataTypeMap;
+ const nonPrimitiveTypes: string[] = Array.from(dataTypeMap.keys()).filter(type => {
+ return primitiveTypes.indexOf(type) === -1;
+ });
+ nonPrimitiveTypes.sort((a, b) => a.localeCompare(b));
+ this.typeList = [...primitiveTypes, ...nonPrimitiveTypes];
+ this.schemaTypeList = Array.from(this.typeList);
+ this.isLoading = false;
+ });
+ return promise;
+ }
+
+ private emitValidityChange(): void {
+ const isValid: boolean = this.formGroup.valid;
+ this.onValidityChange.emit({
+ isValid: isValid,
+ property: isValid ? this.buildPropertyFromForm() : undefined
+ });
+ }
+
+ private buildPropertyFromForm(): PropertyBEModel {
+ const property = new PropertyBEModel();
+ property.name = this.nameForm.value;
+ property.type = this.typeForm.value;
+ if (this.schemaForm.value) {
+ property.schemaType = this.schemaForm.value;
+ }
+ property.description = this.descriptionForm.value;
+ if (this.hasDefaultValueForm.value === true) {
+ property.defaultValue = this.defaultValueForm.value;
+ }
+ return property;
+ }
+
+ public isTypeSimple(): boolean {
+ return ToscaTypeHelper.isTypeSimple(this.typeForm.value);
+ }
+
+ public isTypeList(): boolean {
+ return ToscaTypeHelper.isTypeList(this.typeForm.value);
+ }
+
+ public isTypeMap(): boolean {
+ return ToscaTypeHelper.isTypeMap(this.typeForm.value);
+ }
+
+ public isTypeComplex(): boolean {
+ return ToscaTypeHelper.isTypeComplex(this.typeForm.value);
+ }
+
+ private isTypeRange() {
+ return ToscaTypeHelper.isTypeRange(this.typeForm.value);
+ }
+
+ onPropertyValueChange($event: any): void {
+ this.defaultValueForm.setValue($event.value);
+ }
+
+ showDefaultValue(): boolean {
+ if (this.readOnly) {
+ return this.defaultValueForm.value != undefined && this.dataTypeMap && this.typeForm.valid && this.schemaForm.valid;
+ }
+ return this.dataTypeMap && this.typeForm.valid && this.schemaForm.valid;
+ }
+
+ getDataType(type: string): DataTypeModel {
+ return this.dataTypeMap.get(type);
+ }
+
+ private resetDefaultValue(): void {
+ this.defaultValueForm.reset();
+ if (this.isTypeComplex() || this.isTypeMap()) {
+ this.defaultValueForm.setValue({});
+ } else if (this.isTypeList() || this.isTypeRange()) {
+ this.defaultValueForm.setValue([]);
+ }
+ }
+
+ buildSchemaGroupProperty(): SchemaPropertyGroupModel {
+ const schemaProperty = new SchemaProperty();
+ schemaProperty.type = this.schemaForm.value
+ return new SchemaPropertyGroupModel(schemaProperty);
+ }
+
+}
+
+export class PropertyValidationEvent {
+ isValid: boolean;
+ property: PropertyBEModel;
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html
index 61c319eb6f..ec67a02a1b 100644
--- a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.html
@@ -25,35 +25,36 @@
<input id="search-by-name" type="search" [placeholder]="'SEARCH_LABEL' | translate" [ngModel]="tableFilterTerm" (ngModelChange)="this.tableSearchTermUpdate.next($event)"/>
<span class="sprite magnification-glass search-button"></span>
</div>
+ <div class="add-btn" data-tests-id="add-link" *ngIf="!isViewOnly" (click)="onClickAddProperty()">Add Property</div>
<div class="table-container-flex">
<div class="table" [ngClass]="{'view-mode': isViewOnly}">
<div class="head flex-container">
<div class="table-header head-row hand flex-item" *ngFor="let header of tableHeadersList" (click)="onUpdateSort(header.property)">{{header.title}}
<span *ngIf="tableSortBy === header.property" class="table-header-sort-arrow" [ngClass]="{'down': tableColumnReverse, 'up': !tableColumnReverse}"></span>
</div>
- <div class="table-no-text-header head-row flex-item" *ngIf="!isViewOnly"><span class="delete-col-header"></span></div>
</div>
<div class="body">
- <div *ngIf="filteredProperties.length === 0" class="no-row-text">
- {{'PROPERTY_LIST_EMPTY_MESSAGE' | translate}}
+ <div *ngIf="filteredProperties.length === 0" class="no-row-text">
+ {{'PROPERTY_LIST_EMPTY_MESSAGE' | translate}}
+ </div>
+ <div *ngFor="let property of filteredProperties" [attr.data-tests-id]="'property-row-' + property.name" class="flex-container data-row" (click)="onRowClick(property)">
+ <div class="table-col-general flex-item text" [title]="property.name">
+ <a [attr.data-tests-id]="'property-name-' + property.name" [ngClass]="{'disabled': isViewOnly}">{{property.name}}</a>
</div>
- <div *ngFor="let property of filteredProperties" [attr.data-tests-id]="'property-row-' + property.name" class="flex-container data-row">
- <div class="table-col-general flex-item text" [title]="property.name">
- <a [attr.data-tests-id]="'property-name-' + property.name" [ngClass]="{'disabled': isViewOnly}">{{property.name}}</a>
- </div>
-
- <div class="table-col-general flex-item text" [title]="property.type">
- <span [attr.data-tests-id]="'property-type-' + property.name">{{property.type}}</span>
- </div>
- <div class="table-col-general flex-item text" [title]="property.getSchemaType() || ''">
- <span [attr.data-tests-id]="'property-schema-' + property.name">{{property.getSchemaType() || ''}}</span>
- </div>
- <div class="table-col-general flex-item text" [title]="property.description">
- <span [attr.data-tests-id]="'property-description-' + property.name" [title]="property.description">{{property.description}}</span>
- </div>
- <div class="table-btn-col flex-item" *ngIf="!isViewOnly"></div>
+ <div class="table-col-general flex-item text" [title]="property.type">
+ <span [attr.data-tests-id]="'property-type-' + property.name">{{property.type}}</span>
+ </div>
+ <div class="table-col-general flex-item text" [title]="property.schemaType || ''">
+ <span [attr.data-tests-id]="'property-schema-' + property.name">{{property.schemaType || ''}}</span>
</div>
+ <div class="table-col-general flex-item text" [title]="property.required ? 'Yes' : 'No'">
+ <span [attr.data-tests-id]="'property-required-' + property.name">{{property.required ? 'Yes' : 'No'}}</span>
+ </div>
+ <div class="table-col-general flex-item text" [title]="property.description || ''">
+ <span [attr.data-tests-id]="'property-description-' + property.name" [title]="property.description">{{property.description}}</span>
+ </div>
+ </div>
</div>
</div>
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.less b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.less
index 9c101e8ce3..fd43bd94a1 100644
--- a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.less
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.less
@@ -29,7 +29,7 @@
#left-top-bar {
float: left;
- width: 186px;
+ width: 200px;
::-webkit-input-placeholder {
font-style: italic;
@@ -56,7 +56,7 @@
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
- width: 270px;
+ width: 290px;
height: 32px;
line-height: 32px;
border: 1px solid @main_color_o;
@@ -127,11 +127,15 @@
}
.flex-item:nth-child(4) {
+ flex-grow: 3;
+ }
+
+ .flex-item:nth-child(5) {
flex-grow: 20;
white-space: normal;
}
- .flex-item:nth-child(5) {
+ .flex-item:nth-child(6) {
flex-grow: 3;
padding-top: 10px;
}
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.spec.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.spec.ts
index 6be572d16a..e6e9c12d14 100644
--- a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.spec.ts
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.spec.ts
@@ -30,9 +30,11 @@ import {Observable} from "rxjs/Observable";
import {DataTypeModel} from "../../../../models/data-types";
import {Component, ViewChild} from "@angular/core";
import {PropertyBEModel} from "../../../../models/properties-inputs/property-be-model";
+import {ModalService} from "../../../services/modal.service";
describe('TypeWorkspacePropertiesComponent', () => {
const messages = require("../../../../../assets/languages/en_US.json");
+ let modalService: Partial<ModalService> = {};
let testHostComponent: TestHostComponent;
let testHostFixture: ComponentFixture<TestHostComponent>;
let dataTypeServiceMock: Partial<DataTypeService> = {
@@ -62,7 +64,8 @@ describe('TypeWorkspacePropertiesComponent', () => {
],
providers: [
{provide: DataTypeService, useValue: dataTypeServiceMock},
- {provide: TranslateService, useValue: translateServiceMock}
+ {provide: TranslateService, useValue: translateServiceMock},
+ {provide: ModalService, useValue: modalService}
]
})
.compileComponents();
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts
index 931fd3d97c..90bc89ae08 100644
--- a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace-properties/type-workspace-properties.component.ts
@@ -23,93 +23,173 @@ import {Component, Input, OnInit} from '@angular/core';
import {DataTypeModel} from "../../../../models/data-types";
import {DataTypeService} from "../../../services/data-type.service";
import {PropertyBEModel} from "../../../../models/properties-inputs/property-be-model";
-import { Subject } from "rxjs";
+import {Subject} from "rxjs";
import {debounceTime, distinctUntilChanged} from "rxjs/operators";
+import {ModalService} from "../../../services/modal.service";
+import {ModalModel} from "../../../../models/modal";
+import {ButtonModel} from "../../../../models/button";
+import {TranslateService} from "../../../shared/translator/translate.service";
+import {AddPropertyComponent, PropertyValidationEvent} from "./add-property/add-property.component";
@Component({
- selector: 'app-type-workspace-properties',
- templateUrl: './type-workspace-properties.component.html',
- styleUrls: ['./type-workspace-properties.component.less']
+ selector: 'app-type-workspace-properties',
+ templateUrl: './type-workspace-properties.component.html',
+ styleUrls: ['./type-workspace-properties.component.less']
})
export class TypeWorkspacePropertiesComponent implements OnInit {
- @Input() isViewOnly = true;
- @Input() dataType: DataTypeModel = new DataTypeModel();
-
- properties: Array<PropertyBEModel> = [];
- filteredProperties: Array<PropertyBEModel> = [];
- tableHeadersList: Array<TableHeader> = [];
- tableSortBy: string = 'name';
- tableColumnReverse: boolean = false;
- tableFilterTerm: string = undefined;
- tableSearchTermUpdate = new Subject<string>();
-
- constructor(private dataTypeService: DataTypeService) { }
-
- ngOnInit(): void {
- this.initTable();
- this.initProperties();
- this.tableSearchTermUpdate.pipe(
- debounceTime(400),
- distinctUntilChanged())
- .subscribe(searchTerm => {
- this.filter(searchTerm);
- });
- }
-
- private initTable(): void {
- this.tableHeadersList = [
- {title: 'Name', property: 'name'},
- {title: 'Type', property: 'type'},
- {title: 'Schema', property: 'schema.property.type'},
- {title: 'Description', property: 'description'},
- ];
-
- this.tableSortBy = this.tableHeadersList[0].property;
- }
-
- private initProperties(): void {
- this.dataTypeService.findAllProperties(this.dataType.uniqueId).subscribe(properties => {
- this.properties = properties.map(value => new PropertyBEModel(value));
- this.filteredProperties = Array.from(this.properties);
- this.sort();
- });
- }
-
- onUpdateSort(property: string): void {
- if (this.tableSortBy === property) {
- this.tableColumnReverse = !this.tableColumnReverse;
- } else {
- this.tableColumnReverse = false;
- this.tableSortBy = property;
+ @Input() isViewOnly = true;
+ @Input() dataType: DataTypeModel = new DataTypeModel();
+
+ properties: Array<PropertyBEModel> = [];
+ filteredProperties: Array<PropertyBEModel> = [];
+ tableHeadersList: Array<TableHeader> = [];
+ tableSortBy: string = 'name';
+ tableColumnReverse: boolean = false;
+ tableFilterTerm: string = undefined;
+ tableSearchTermUpdate = new Subject<string>();
+
+ constructor(private dataTypeService: DataTypeService, private modalService: ModalService, private translateService: TranslateService) {
+ }
+
+ ngOnInit(): void {
+ this.initTable();
+ this.initProperties();
+ this.tableSearchTermUpdate.pipe(
+ debounceTime(400),
+ distinctUntilChanged())
+ .subscribe(searchTerm => {
+ this.filter(searchTerm);
+ });
+ }
+
+ private initTable(): void {
+ this.tableHeadersList = [
+ {title: 'Name', property: 'name'},
+ {title: 'Type', property: 'type'},
+ {title: 'Schema', property: 'schema.property.type'},
+ {title: 'Required', property: 'required'},
+ {title: 'Description', property: 'description'},
+ ];
+
+ this.tableSortBy = this.tableHeadersList[0].property;
}
- this.sort();
- }
-
- private sort(): void {
- const field = this.tableSortBy;
- this.filteredProperties = this.filteredProperties.sort((property1, property2) => {
- const result = property1[field] > property2[field] ? 1 : property1[field] < property2[field] ? -1 : 0;
- return this.tableColumnReverse ? result * -1 : result;
- });
- }
-
- private filter(searchTerm: string): void {
- if (searchTerm) {
- searchTerm = searchTerm.toLowerCase();
- this.filteredProperties = this.properties.filter(property =>
- property.name.toLowerCase().includes(searchTerm)
- || property.type.toLowerCase().includes(searchTerm)
- || (property.getSchemaType() && property.getSchemaType().toLowerCase().includes(searchTerm))
- || (property.description && property.description.toLowerCase().includes(searchTerm))
- );
- } else {
- this.filteredProperties = Array.from(this.properties);
+
+ private initProperties(): void {
+ this.dataTypeService.findAllProperties(this.dataType.uniqueId).subscribe(properties => {
+ this.properties = properties.map(value => {
+ const property = new PropertyBEModel(value);
+ if (property.defaultValue) {
+ property.defaultValue = JSON.parse(property.defaultValue);
+ }
+
+ return property;
+ });
+ this.filteredProperties = Array.from(this.properties);
+ this.sort();
+ });
+ }
+
+ onUpdateSort(property: string): void {
+ if (this.tableSortBy === property) {
+ this.tableColumnReverse = !this.tableColumnReverse;
+ } else {
+ this.tableColumnReverse = false;
+ this.tableSortBy = property;
+ }
+ this.sort();
+ }
+
+ private sort(): void {
+ const field = this.tableSortBy;
+ this.filteredProperties.sort((property1, property2) => {
+ let result = 0;
+ if (property1[field] > property2[field]) {
+ result = 1;
+ } else if (property1[field] < property2[field]) {
+ result = -1;
+ }
+ return this.tableColumnReverse ? result * -1 : result;
+ });
+ }
+
+ private filter(searchTerm?: string): void {
+ if (searchTerm) {
+ searchTerm = searchTerm.toLowerCase();
+ this.filteredProperties = this.properties.filter(property =>
+ property.name.toLowerCase().includes(searchTerm)
+ || property.type.toLowerCase().includes(searchTerm)
+ || (property.getSchemaType() && property.getSchemaType().toLowerCase().includes(searchTerm))
+ || (property.description && property.description.toLowerCase().includes(searchTerm))
+ );
+ } else {
+ this.filteredProperties = Array.from(this.properties);
+ }
+ this.sort();
+ }
+
+ private addProperty(property: PropertyBEModel) {
+ this.properties.push(property);
+ this.filter();
+ }
+
+ onClickAddProperty() {
+ this.openAddPropertyModal();
+ }
+
+ private openAddPropertyModal(property?: PropertyBEModel, readOnly: boolean = false) {
+ const modalTitle = this.translateService.translate('PROPERTY_ADD_MODAL_TITLE');
+ const modalButtons = [];
+ let disableSaveButtonFlag = true;
+ let propertyFromModal: PropertyBEModel = undefined;
+ const modal = this.modalService.createCustomModal(new ModalModel(
+ 'md',
+ modalTitle,
+ null,
+ modalButtons,
+ null
+ ));
+ if (readOnly) {
+ modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CLOSE'), 'outline grey', () => {
+ this.modalService.closeCurrentModal();
+ }));
+ } else {
+ modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
+ () => {
+ disableSaveButtonFlag = true;
+ this.dataTypeService.createProperty(this.dataType.uniqueId, propertyFromModal).subscribe(property => {
+ this.addProperty(new PropertyBEModel(property));
+ });
+ this.modalService.closeCurrentModal();
+ },
+ (): boolean => {
+ return disableSaveButtonFlag
+ }
+ ));
+
+ modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
+ this.modalService.closeCurrentModal();
+ }));
+ }
+
+ this.modalService.addDynamicContentToModalAndBindInputs(modal, AddPropertyComponent, {
+ 'readOnly': readOnly,
+ 'property': property
+ });
+ modal.instance.dynamicContent.instance.onValidityChange.subscribe((validationEvent: PropertyValidationEvent) => {
+ disableSaveButtonFlag = !validationEvent.isValid;
+ if (validationEvent.isValid) {
+ propertyFromModal = validationEvent.property;
+ }
+ });
+ modal.instance.open();
+ }
+
+ onRowClick(property: PropertyBEModel) {
+ this.openAddPropertyModal(property, true);
}
- this.sort();
- }
}
interface TableHeader {
- title: string;
- property: string;
+ title: string;
+ property: string;
} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.html b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.html
index 193c94e6ad..4d29e8673a 100644
--- a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.html
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.component.html
@@ -44,7 +44,7 @@
</div>
<div class="w-sdc-main-container-body-content" *ngIf="dataType">
<app-type-workspace-general *ngIf="currentMenu.state === 'general'" [dataType]="dataType"></app-type-workspace-general>
- <app-type-workspace-properties *ngIf="currentMenu.state === 'properties'" [dataType]="dataType"></app-type-workspace-properties>
+ <app-type-workspace-properties *ngIf="currentMenu.state === 'properties'" [dataType]="dataType" [isViewOnly]="false"></app-type-workspace-properties>
</div>
</div>
diff --git a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.module.ts b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.module.ts
index 021f84af09..5b2d3bf030 100644
--- a/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.module.ts
+++ b/catalog-ui/src/app/ng2/pages/type-workspace/type-workspace.module.ts
@@ -31,7 +31,10 @@ import {UpgradeModule} from "@angular/upgrade/static";
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {TranslateModule} from "../../shared/translator/translate.module";
import {DataTypeService} from "../../services/data-type.service";
-import { TypeWorkspacePropertiesComponent } from './type-workspace-properties/type-workspace-properties.component';
+import {TypeWorkspacePropertiesComponent} from './type-workspace-properties/type-workspace-properties.component';
+import {ModalService} from "../../services/modal.service";
+import {AddPropertyComponent} from './type-workspace-properties/add-property/add-property.component';
+import {InterfaceOperationHandlerModule} from "../composition/interface-operatons/operation-creator/interface-operation-handler.module";
@NgModule({
imports: [
@@ -42,19 +45,22 @@ import { TypeWorkspacePropertiesComponent } from './type-workspace-properties/ty
ReactiveFormsModule,
TranslateModule,
FormsModule,
+ InterfaceOperationHandlerModule,
],
declarations: [
TypeWorkspaceComponent,
WorkspaceMenuComponent,
TypeWorkspaceGeneralComponent,
- TypeWorkspacePropertiesComponent
+ TypeWorkspacePropertiesComponent,
+ AddPropertyComponent,
],
providers: [
CacheService,
WorkspaceMenuComponent,
- DataTypeService
+ DataTypeService,
+ ModalService
],
- entryComponents: [TypeWorkspaceComponent],
+ entryComponents: [TypeWorkspaceComponent, AddPropertyComponent],
exports: [TypeWorkspaceComponent]
})
export class TypeWorkspaceModule {
diff --git a/catalog-ui/src/app/ng2/services/data-type.service.ts b/catalog-ui/src/app/ng2/services/data-type.service.ts
index 74d48d35de..298ba90b31 100644
--- a/catalog-ui/src/app/ng2/services/data-type.service.ts
+++ b/catalog-ui/src/app/ng2/services/data-type.service.ts
@@ -83,6 +83,11 @@ export class DataTypeService {
return this.httpClient.get<Array<PropertyBEModel>>(url);
}
+ public createProperty(id: string, property: PropertyBEModel): Observable<PropertyBEModel> {
+ const url = `${this.dataTypeUrl}/${id}/properties`
+ return this.httpClient.post<PropertyBEModel>(url, property);
+ }
+
public getConstraintsByParentTypeAndUniqueID(rootPropertyType, propertyName){
// const property = this.dataTypes[rootPropertyType].properties.filter(property =>
// property.name == propertyName);
diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts
index 9d11f54db9..c8fb1966b4 100644
--- a/catalog-ui/src/app/utils/constants.ts
+++ b/catalog-ui/src/app/utils/constants.ts
@@ -156,6 +156,7 @@ export class PROPERTY_DATA {
public static TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.TIMESTAMP, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.BOOLEAN, PROPERTY_TYPES.JSON, PROPERTY_TYPES.SCALAR, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME, PROPERTY_TYPES.LIST, PROPERTY_TYPES.MAP, PROPERTY_TYPES.RANGE];
public static SIMPLE_TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.TIMESTAMP, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.BOOLEAN, PROPERTY_TYPES.JSON, PROPERTY_TYPES.SCALAR, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME];
public static SIMPLE_TYPES_COMPARABLE = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT];
+ public static SCHEMA_TYPES = [PROPERTY_TYPES.LIST, PROPERTY_TYPES.MAP];
public static SCALAR_TYPES = [PROPERTY_TYPES.SCALAR, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME];
public static ROOT_DATA_TYPE = "tosca.datatypes.Root";
public static OPENECOMP_ROOT = "org.openecomp.datatypes.Root";
diff --git a/catalog-ui/src/app/utils/tosca-type-helper.ts b/catalog-ui/src/app/utils/tosca-type-helper.ts
new file mode 100644
index 0000000000..7faa90a7fe
--- /dev/null
+++ b/catalog-ui/src/app/utils/tosca-type-helper.ts
@@ -0,0 +1,78 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {DerivedPropertyType} from "../models/properties-inputs/property-be-model";
+import {PROPERTY_DATA, PROPERTY_TYPES} from "./constants";
+
+export class ToscaTypeHelper {
+
+ private ToscaTypeHelper() {
+ //not designed to be instantiated
+ }
+
+ public static getType(typeName: string): DerivedPropertyType {
+ if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(typeName) > -1) {
+ return DerivedPropertyType.SIMPLE;
+ } else if (typeName === PROPERTY_TYPES.LIST) {
+ return DerivedPropertyType.LIST;
+ } else if (typeName === PROPERTY_TYPES.MAP) {
+ return DerivedPropertyType.MAP;
+ } else if (typeName === PROPERTY_TYPES.RANGE) {
+ return DerivedPropertyType.RANGE;
+ } else {
+ return DerivedPropertyType.COMPLEX;
+ }
+ }
+
+ public static isTypeSimple(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.SIMPLE;
+ }
+
+ public static isTypeList(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.LIST;
+ }
+
+ public static isTypeMap(typeName: string): boolean {
+ return this.getType(typeName) == DerivedPropertyType.MAP;
+ }
+
+ public static isTypeComplex(typeName: string): boolean {
+ return !this.isTypeSimple(typeName) && !this.isTypeList(typeName) && !this.isTypeMap(typeName);
+ }
+
+ public static isTypeNumber(typeName: string): boolean {
+ return typeName === PROPERTY_TYPES.INTEGER || typeName === PROPERTY_TYPES.FLOAT;
+ }
+
+ public static isTypeBoolean(typeName: string): boolean {
+ return typeName === PROPERTY_TYPES.BOOLEAN;
+ }
+
+ public static isTypeLiteral(typeName: string): boolean {
+ return !this.isTypeNumber(typeName) && !this.isTypeBoolean(typeName) && !this.isTypeList(typeName) && !this.isTypeMap(typeName)
+ && !this.isTypeComplex(typeName) && !this.isTypeRange(typeName);
+ }
+
+ public static isTypeRange(typeName: string): boolean {
+ return typeName === PROPERTY_TYPES.RANGE;
+ }
+
+}
diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json
index fc5445a6c3..5dec922980 100644
--- a/catalog-ui/src/assets/languages/en_US.json
+++ b/catalog-ui/src/assets/languages/en_US.json
@@ -41,6 +41,10 @@
"GENERAL_LABEL_SYSTEM_NAME": "System Name:",
"GENERAL_LABEL_SOURCE_SERVICE_NAME": "Source Service Name:",
"GENERAL_LABEL_RESOURCE_CUSTOMIZATION_UUID": "Resource Customization UUID:",
+ "GENERAL_LABEL_EMPTY": "Empty",
+ "GENERAL_LABEL_TRUE": "True",
+ "GENERAL_LABEL_FALSE": "False",
+ "GENERAL_LABEL_SELECT": "Select",
"SEARCH_LABEL": "Search",
"=========== GENERAL_TAB ===========": "",
"GENERAL_TAB_LABEL_RESOURCE_MODEL_NUMBER": "Vendor Model Number",
@@ -506,6 +510,7 @@
"MODAL_SAVE": "Save",
"MODAL_CREATE": "Create",
"MODAL_CANCEL": "Cancel",
+ "MODAL_CLOSE": "Close",
"MODAL_DELETE": "Delete",
"=========== POLICY AND GROUPS ===========": "",
"ADD_TARGETS": "Add Targets",
@@ -582,5 +587,14 @@
"IMPORT_FAILURE_MESSAGE_TEXT": "Import Failure - error reading CSAR",
"=========== PROPERTIES ===========": "",
"PROPERTY_LIST_EMPTY_MESSAGE": "There are no properties to display",
- "PROPERTY_SHOWING_LABEL": "Showing Properties"
+ "PROPERTY_SHOWING_LABEL": "Showing Properties",
+ "PROPERTY_ADD_MODAL_TITLE": "Add Property",
+ "PROPERTY_VIEW_MODAL_TITLE": "View Property",
+ "PROPERTY_DESCRIPTION_LABEL": "Description",
+ "PROPERTY_DEFAULT_VALUE_LABEL": "Default Value",
+ "PROPERTY_SCHEMA_LABEL": "Schema",
+ "PROPERTY_REQUIRED_LABEL": "Required",
+ "PROPERTY_TYPE_LABEL": "Type",
+ "PROPERTY_SET_DEFAULT_VALUE_MSG": "Set Default Value?",
+ "PROPERTY_NAME_LABEL": "Name"
}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java
index c023401deb..3fcbc0fbe8 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java
@@ -33,6 +33,7 @@ import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinit
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.Select;
/**
* Handles the input list inside the interface operation modal.
@@ -71,10 +72,14 @@ public class InterfaceOperationInputListComponent extends AbstractPageObject {
if (value == null) {
return;
}
- if (value instanceof String || value instanceof Integer || value instanceof Boolean) {
+ if (value instanceof String || value instanceof Integer) {
fillSimpleValue(inputName, String.valueOf(value));
return;
}
+ if (value instanceof Boolean) {
+ fillBooleanValue(inputName, String.valueOf(value));
+ return;
+ }
throw new UnsupportedOperationException("Set input value not yet implemented for value type: " + value.getClass().getName());
}
@@ -141,6 +146,15 @@ public class InterfaceOperationInputListComponent extends AbstractPageObject {
inputOpt.ifPresent(webElement -> webElement.findElement(simpleInputValueSelector).sendKeys(inputValue));
}
+ private void fillBooleanValue(final String inputName, final String inputValue) {
+ toggleInputExpansion(inputName);
+ final Optional<WebElement> inputOpt = findInput(inputName);
+ assertTrue(inputOpt.isPresent(), String.format("Could not set value for input '%s'. The input was not found.", inputName));
+ final By simpleInputValueSelector = By.xpath(XpathSelector.BOOLEAN_VALUE_INPUT_RELATIVE_FROM_INPUT_INFO.getXPath());
+ final WebElement booleanDropdownWebElement = inputOpt.get().findElement(simpleInputValueSelector);
+ new Select(booleanDropdownWebElement).selectByValue(inputValue);
+ }
+
@AllArgsConstructor
private enum XpathSelector {
WRAPPING_ELEMENT("//div[@class='input-tree']"),
@@ -148,6 +162,7 @@ public class InterfaceOperationInputListComponent extends AbstractPageObject {
INPUT_LABEL("label[@class='input-label']"),
INPUT_TYPE("em[@data-tests-id='input-type']"),
SIMPLE_VALUE_INPUT_RELATIVE_FROM_INPUT_INFO("..//li[@class='input-value']/input"),
+ BOOLEAN_VALUE_INPUT_RELATIVE_FROM_INPUT_INFO("..//li[@class='input-value']/select"),
EXPAND_ICON("em[contains(concat(' ',normalize-space(@class),' '),' round-expand-icon ')]"),
DELETE_ICON("span[contains(concat(' ',normalize-space(@class),' '),' delete-btn ')]");