summaryrefslogtreecommitdiffstats
path: root/model/src
diff options
context:
space:
mode:
authorliamfallon <liam.fallon@est.tech>2022-02-10 12:06:25 +0000
committerliamfallon <liam.fallon@est.tech>2022-02-10 13:48:15 +0000
commit8534756d13531ffec9c2d7b2ffe0a53ee1d3aaef (patch)
treea35f6b3f7766d47900ee6691111acff1418bb747 /model/src
parent2f2c5465cd23c8c3300a5c3d185806bb3e7d73c1 (diff)
Collapse apex-pdp maven model submodules
This review collapses all the code in six podel submodules into a single model module. There are no code changes, just files moved around. This change reduces the complexity of the code structure and speeds up the build. Issue-ID: POLICY-1820 Change-Id: Ifb644e8ec85ae6d0987378f4616fbc8a8858a9a8 Signed-off-by: liamfallon <liam.fallon@est.tech>
Diffstat (limited to 'model/src')
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexConceptException.java49
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexException.java111
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexRuntimeException.java93
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxArtifactKey.java344
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConcept.java137
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetter.java77
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetterImpl.java143
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKey.java105
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfo.java317
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInformation.java389
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyUse.java221
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxModel.java423
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxReferenceKey.java527
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxToscaPolicyProcessingStatus.java46
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxValidationMessage.java104
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxValidationResult.java150
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/package-info.java27
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCreator.java41
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCustomGsonMapAdapter.java118
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCustomGsonRefereceKeyAdapter.java50
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelException.java51
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelFileWriter.java99
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReader.java169
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelSaver.java80
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelStringWriter.java94
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriter.java148
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/package-info.java21
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/package-info.java31
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/service/ModelService.java108
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/service/package-info.java26
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/test/TestApexModel.java259
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/test/TestApexModelCreator.java62
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/basicmodel/test/package-info.java26
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbum.java268
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbums.java310
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextModel.java222
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextSchema.java299
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextSchemas.java304
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/package-info.java28
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/contextmodel/handling/ContextComparer.java70
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/contextmodel/handling/package-info.java27
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineModel.java338
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineState.java52
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineStats.java533
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/package-info.java28
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEvent.java547
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEventModel.java276
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEvents.java351
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxField.java347
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxInputField.java88
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxOutputField.java88
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/package-info.java27
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/ApexApiResult.java264
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/ApexEditorApi.java905
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/ApexModel.java176
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/ApexModelFactory.java76
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ApexModelImpl.java866
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbum.java39
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbumFacade.java254
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextSchemaFacade.java238
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/CreatePolicyStateTaskRef.java38
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/EventFacade.java386
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/KeyInformationFacade.java228
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelFacade.java202
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java498
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/PolicyFacade.java1385
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/TaskFacade.java597
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/impl/package-info.java27
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/modelapi/package-info.java27
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogic.java355
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogicReader.java74
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicies.java360
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicy.java508
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java661
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java870
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateFinalizerLogic.java121
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java291
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateParamsBuilder.java162
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskOutputType.java42
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java339
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java173
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTask.java405
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskLogic.java120
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskParameter.java253
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskSelectionLogic.java119
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTasks.java351
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyException.java51
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyRuntimeException.java51
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/package-info.java28
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyser.java178
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalysisResult.java266
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyComparer.java46
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReader.java142
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparer.java268
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java183
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitter.java165
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/policymodel/handling/package-info.java26
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/CollectionUtils.java109
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/DirectoryDeleteShutdownHook.java67
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/DirectoryUtils.java110
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/TreeMapUtils.java126
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyComparer.java42
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyDifference.java86
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapComparer.java96
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapDifference.java174
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/comparison/package-info.java26
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/json/JsonHandler.java50
-rwxr-xr-xmodel/src/main/java/org/onap/policy/apex/model/utilities/json/package-info.java26
-rw-r--r--model/src/main/java/org/onap/policy/apex/model/utilities/package-info.java26
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetterImplTest.java84
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfoTest.java108
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyTest.java189
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyUseTest.java78
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxReferenceKeyTest.java177
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/DummyEntity.java164
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/ExceptionsTest.java66
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/ValidationTest.java90
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelExceptionTest.java39
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelFileWriterTest.java94
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReaderTest.java105
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelSaverTest.java52
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelStringWriterTest.java63
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriterTest.java67
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/DummyApexBasicModelCreator.java123
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/DummyAxModelWithReferences.java71
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexBasicModelConceptsTest.java294
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexBasicModelTest.java116
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator0.java64
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator1.java68
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator2.java64
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportBasicModelTest.java111
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportConceptGetterTest.java217
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/basicmodel/service/ModelServiceTest.java65
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextAlbumsTest.java248
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextModelTest.java95
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextSchemasTest.java229
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/ApexContextModelTest.java124
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/ContextComparisonTest.java189
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/TestApexContextModelCreator.java122
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/TestContextComparisonFactory.java148
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/enginemodel/concepts/EngineModelTest.java176
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/enginemodel/concepts/EngineStatsTest.java267
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/enginemodel/handling/ApexEngineModelTest.java81
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/enginemodel/handling/DummyTestApexEngineModelCreator.java129
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/EventModelTest.java87
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/EventsTest.java323
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/FieldTest.java134
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/eventmodel/handling/ApexEventModelTest.java279
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/eventmodel/handling/DummyTestApexEventModelCreator.java309
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ApexApiResultTest.java80
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiContextAlbumTest.java176
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiContextSchemaTest.java153
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiEventTest.java202
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiKeyInfoTest.java137
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiPolicyTest.java1023
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiTaskTest.java376
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ApexModelApiTest.java208
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ModelFacadeTest.java99
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/ModelHandlerFacadeTest.java128
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/modelapi/RealModelTest.java46
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/DummyLogicReader.java65
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/ExceptionsTest.java51
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/LogicTest.java161
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/PoliciesTest.java391
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/PolicyModelTest.java312
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateOutputTest.java124
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateTaskReferenceTest.java144
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateTest.java461
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TaskParameterTest.java110
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TasksTest.java259
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/handling/ApexPolicyModelTest.java138
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyserTest.java60
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReaderTest.java84
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparerTest.java118
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMergerTest.java92
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitterTest.java76
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/handling/SupportApexPolicyModelCreator.java406
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/policymodel/utils/SupportPolicyModelValidator.java48
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/utilities/CollectionUtilitiesTest.java87
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/utilities/DirectoryUtilsTest.java55
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/utilities/KeyComparerTest.java53
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/utilities/KeyedMapComparerTest.java76
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/utilities/TextFileUtilsTest.java56
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/utilities/TreeMapUtilsTest.java157
-rw-r--r--model/src/test/java/org/onap/policy/apex/model/utilities/json/JsonHandlerTest.java59
-rw-r--r--model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt12
-rw-r--r--model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt12
-rw-r--r--model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt70
-rw-r--r--model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt70
-rw-r--r--model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt8
-rw-r--r--model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt69
-rw-r--r--model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt68
-rw-r--r--model/src/test/resources/logback-test.xml78
-rw-r--r--model/src/test/resources/models/PolicyModel.json775
-rw-r--r--model/src/test/resources/models/PolicyModel.junk9
-rw-r--r--model/src/test/resources/models/RealPolicyModel.json3076
-rw-r--r--model/src/test/resources/path/to/apex/logic/funkylogic/LogicParentLogicParentLocalNameLogicInstanceName.funkylogic21
-rw-r--r--model/src/test/resources/testdir/testfile.xml20
198 files changed, 38669 insertions, 0 deletions
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexConceptException.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexConceptException.java
new file mode 100644
index 000000000..d62818dc8
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexConceptException.java
@@ -0,0 +1,49 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+/**
+ * This class is an exception thrown on Apex Concept errors.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexConceptException extends ApexException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ /**
+ * Instantiates a new apex concept exception.
+ *
+ * @param message the message on the exception
+ */
+ public ApexConceptException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new apex concept exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this Apex exception
+ */
+ public ApexConceptException(final String message, final Exception exception) {
+ super(message, exception);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexException.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexException.java
new file mode 100644
index 000000000..2eca2f783
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexException.java
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 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.onap.policy.apex.model.basicmodel.concepts;
+
+/**
+ * This class is a base exception from which all Apex exceptions are sub classes.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexException extends Exception {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ // The object on which the exception was thrown
+ private final transient Object object;
+
+ /**
+ * Instantiates a new apex exception.
+ *
+ * @param message the message on the exception
+ */
+ public ApexException(final String message) {
+ this(message, null);
+ }
+
+ /**
+ * Instantiates a new apex exception.
+ *
+ * @param message the message on the exception
+ * @param object the object that the exception was thrown on
+ */
+ public ApexException(final String message, final Object object) {
+ super(message);
+ this.object = object;
+ }
+
+ /**
+ * Instantiates a new apex exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this Apex exception
+ */
+ public ApexException(final String message, final Exception exception) {
+ this(message, exception, null);
+ }
+
+ /**
+ * Instantiates a new apex exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this Apex exception
+ * @param object the object that the exception was thrown on
+ */
+ public ApexException(final String message, final Exception exception, final Object object) {
+ super(message, exception);
+ this.object = object;
+ }
+
+ /**
+ * Get the message from this exception and its causes.
+ *
+ * @return the cascaded messages from this exception and the exceptions that caused it
+ */
+ public String getCascadedMessage() {
+ return buildCascadedMessage(this);
+ }
+
+ /**
+ * Build a cascaded message from an exception and all its nested exceptions.
+ * @param throwable the top level exception
+ * @return cascaded message string
+ */
+ public static String buildCascadedMessage(Throwable throwable) {
+ final var builder = new StringBuilder();
+ builder.append(throwable.getMessage());
+
+ for (var t = throwable; t != null; t = t.getCause()) {
+ builder.append("\ncaused by: ");
+ builder.append(t.getMessage());
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Get the object on which the exception was thrown.
+ *
+ * @return The object on which the exception was thrown
+ */
+ public Object getObject() {
+ return object;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexRuntimeException.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexRuntimeException.java
new file mode 100644
index 000000000..b4240ad0f
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/ApexRuntimeException.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+/**
+ * This class is a base run time exception from which all Apex run time exceptions are sub classes.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexRuntimeException extends RuntimeException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ // The object on which the exception was thrown
+ private final transient Object object;
+
+ /**
+ * Instantiates a new apex runtime exception.
+ *
+ * @param message the message on the exception
+ */
+ public ApexRuntimeException(final String message) {
+ this(message, null);
+ }
+
+ /**
+ * Instantiates a new apex runtime exception.
+ *
+ * @param message the message on the exception
+ * @param object the object that the exception was thrown on
+ */
+ public ApexRuntimeException(final String message, final Object object) {
+ super(message);
+ this.object = object;
+ }
+
+ /**
+ * Instantiates a new apex runtime exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this Apex exception
+ */
+ public ApexRuntimeException(final String message, final Exception exception) {
+ this(message, exception, null);
+ }
+
+ /**
+ * Instantiates a new apex runtime exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this Apex exception
+ * @param object the object that the exception was thrown on
+ */
+ public ApexRuntimeException(final String message, final Exception exception, final Object object) {
+ super(message, exception);
+ this.object = object;
+ }
+
+ /**
+ * Get the message from this exception and its causes.
+ *
+ * @return the message of this exception and all the exceptions that caused this exception
+ */
+ public String getCascadedMessage() {
+ return ApexException.buildCascadedMessage(this);
+ }
+
+ /**
+ * Get the object on which the exception was thrown.
+ *
+ * @return The object
+ */
+ public Object getObject() {
+ return object;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxArtifactKey.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxArtifactKey.java
new file mode 100644
index 000000000..1efe83db8
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxArtifactKey.java
@@ -0,0 +1,344 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * An artifact key uniquely identifies every first order entity in the system. Every first order concept in the system
+ * must have an {@link AxArtifactKey} to identify it. Concepts that are wholly contained in another concept are
+ * identified using a {@link AxReferenceKey} key.
+ *
+ * <p>Key validation checks that the name and version fields match the NAME_REGEXP and VERSION_REGEXP
+ * regular expressions respectively.
+ */
+public class AxArtifactKey extends AxKey {
+ private static final long serialVersionUID = 8932717618579392561L;
+
+ private static final String NAME_TOKEN = "name";
+ private static final String VERSION_TOKEN = "version";
+
+ private String name;
+ private String version;
+
+ /**
+ * The default constructor creates a null artifact key.
+ */
+ public AxArtifactKey() {
+ this(NULL_KEY_NAME, NULL_KEY_VERSION);
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxArtifactKey(final AxArtifactKey copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor to create a key with the specified name and version.
+ *
+ * @param name the key name
+ * @param version the key version
+ */
+ public AxArtifactKey(final String name, final String version) {
+ super();
+ this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+ this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+ }
+
+ /**
+ * Constructor to create a key using the key and version from the specified key ID.
+ *
+ * @param id the key ID in a format that respects the KEY_ID_REGEXP
+ */
+ public AxArtifactKey(final String id) {
+ Assertions.argumentNotNull(id, "id may not be null");
+
+ // Check the incoming ID is valid
+ Assertions.validateStringParameter("id", id, KEY_ID_REGEXP);
+
+ // Split on colon, if the id passes the regular expression test above
+ // it'll have just one colon separating the name and version
+ // No need for range checks or size checks on the array
+ final String[] nameVersionArray = id.split(":");
+
+ // Return the new key
+ name = Assertions.validateStringParameter(NAME_TOKEN, nameVersionArray[0], NAME_REGEXP);
+ version = Assertions.validateStringParameter(VERSION_TOKEN, nameVersionArray[1], VERSION_REGEXP);
+ }
+
+ /**
+ * Get a null artifact key.
+ *
+ * @return a null artifact key
+ */
+ public static final AxArtifactKey getNullKey() {
+ return new AxArtifactKey(AxKey.NULL_KEY_NAME, AxKey.NULL_KEY_VERSION);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = new ArrayList<>();
+ keyList.add(getKey());
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getId() {
+ return name + ':' + version;
+ }
+
+ /**
+ * Gets the key name.
+ *
+ * @return the key name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the key name.
+ *
+ * @param name the key name
+ */
+ public void setName(final String name) {
+ this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+ }
+
+ /**
+ * Gets the key version.
+ *
+ * @return the key version
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * Sets the key version.
+ *
+ * @param version the key version
+ */
+ public void setVersion(final String version) {
+ this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+ }
+
+ /**
+ * Check if the key is IDENTICAL to a null key.
+ *
+ * @return true, if the key is IDENTICAL to a null key
+ */
+ public boolean isNullKey() {
+ return this.getCompatibility(AxArtifactKey.getNullKey()).equals(AxKey.Compatibility.IDENTICAL);
+ }
+
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxKey.Compatibility getCompatibility(final AxKey otherKey) {
+ if (!(otherKey instanceof AxArtifactKey)) {
+ return Compatibility.DIFFERENT;
+ }
+ final AxArtifactKey otherArtifactKey = (AxArtifactKey) otherKey;
+
+ if (this.equals(otherArtifactKey)) {
+ return Compatibility.IDENTICAL;
+ }
+ if (!this.getName().equals(otherArtifactKey.getName())) {
+ return Compatibility.DIFFERENT;
+ }
+
+ final String[] thisVersionArray = getVersion().split("\\.");
+ final String[] otherVersionArray = otherArtifactKey.getVersion().split("\\.");
+
+ // There must always be at least one element in each version
+ if (!thisVersionArray[0].equals(otherVersionArray[0])) {
+ return Compatibility.MAJOR;
+ }
+
+ if (thisVersionArray.length >= 2 && otherVersionArray.length >= 2
+ && !thisVersionArray[1].equals(otherVersionArray[1])) {
+ return Compatibility.MINOR;
+ }
+
+ return Compatibility.PATCH;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean isCompatible(final AxKey otherKey) {
+ if (!(otherKey instanceof AxArtifactKey)) {
+ return false;
+ }
+ final AxArtifactKey otherArtifactKey = (AxArtifactKey) otherKey;
+
+ final var compatibility = this.getCompatibility(otherArtifactKey);
+
+ return !(compatibility == Compatibility.DIFFERENT || compatibility == Compatibility.MAJOR);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult result) {
+ final var nameValidationErrorMessage = Assertions.getStringParameterValidationMessage(NAME_TOKEN, name,
+ NAME_REGEXP);
+ if (nameValidationErrorMessage != null) {
+ result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+ "name invalid-" + nameValidationErrorMessage));
+ }
+
+ final var versionValidationErrorMessage = Assertions.getStringParameterValidationMessage(VERSION_TOKEN,
+ version, VERSION_REGEXP);
+ if (versionValidationErrorMessage != null) {
+ result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+ "version invalid-" + versionValidationErrorMessage));
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+ version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final var builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("name=");
+ builder.append(name);
+ builder.append(",version=");
+ builder.append(version);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final AxConcept copyObject = target;
+ Assertions.instanceOf(copyObject, AxArtifactKey.class);
+
+ final AxArtifactKey copy = ((AxArtifactKey) copyObject);
+ copy.setName(name);
+ copy.setVersion(version);
+
+ return copyObject;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final var prime = 31;
+ var result = 1;
+ result = prime * result + name.hashCode();
+ result = prime * result + version.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxArtifactKey other = (AxArtifactKey) obj;
+
+ if (!name.equals(other.name)) {
+ return false;
+ }
+ return version.equals(other.version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxArtifactKey other = (AxArtifactKey) otherObj;
+
+ if (!name.equals(other.name)) {
+ return name.compareTo(other.name);
+ }
+ return version.compareTo(other.version);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConcept.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConcept.java
new file mode 100644
index 000000000..37fe30b33
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConcept.java
@@ -0,0 +1,137 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.io.Serializable;
+import java.util.List;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is the base class for all Apex concept classes. It enforces implementation of abstract methods and
+ * interfaces on all concepts that are sub-classes of this class.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public abstract class AxConcept implements Serializable, Comparable<AxConcept> {
+ private static final long serialVersionUID = -7434939557282697490L;
+
+ /**
+ * Default constructor.
+ */
+ protected AxConcept() {
+ // Default constructor
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ protected AxConcept(final AxConcept copyConcept) {
+ Assertions.argumentNotNull(copyConcept, "copy concept may not be null");
+ copyConcept.copyTo(this);
+ }
+
+ /**
+ * Gets the key of this concept.
+ *
+ * @return the concept key
+ */
+ public abstract AxKey getKey();
+
+ /**
+ * Gets a list of all keys for this concept and all concepts that are defined or referenced by this concept and its
+ * sub-concepts.
+ *
+ * @return the keys used by this concept and it's contained concepts
+ */
+ public abstract List<AxKey> getKeys();
+
+ /**
+ * Validate that this concept is structurally correct.
+ *
+ * @param result the parameter in which the result of the validation will be returned
+ * @return the validation result that was passed in in the @{link result} field with the result of this validation
+ * added
+ */
+ public abstract AxValidationResult validate(AxValidationResult result);
+
+ /**
+ * Clean this concept, tidy up any superfluous information such as leading and trailing white space.
+ */
+ public abstract void clean();
+
+ /**
+ * Builds references used by a concept.
+ */
+ public void buildReferences() {
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public abstract boolean equals(Object otherObject);
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public abstract String toString();
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public abstract int hashCode();
+
+ /**
+ * Copy this concept to another object. The target object must have the same class as the source object.
+ *
+ * @param target the target object to which this object is copied
+ * @return the copied object
+ */
+ public abstract AxConcept copyTo(AxConcept target);
+
+ /**
+ * Gets the ID string of this concept.
+ *
+ * @return the ID string of this concept
+ */
+ public String getId() {
+ return getKey().getId();
+ }
+
+ /**
+ * Checks if this key matches the given key ID.
+ *
+ * @param id the key ID to match against
+ * @return true, if this key matches the ID
+ */
+ public final boolean matchesId(final String id) {
+ Assertions.argumentNotNull(id, "id may not be null");
+
+ // Check the ID
+ return getId().equals(id);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetter.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetter.java
new file mode 100644
index 000000000..0284de48a
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetter.java
@@ -0,0 +1,77 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.Set;
+
+/**
+ * This interface is used to allow get methods to be placed on concepts that have embedded maps.
+ *
+ * <p>It forces those concepts with maps to implement the get methods specified on this interface as convenience methods
+ * to avoid concept users having to use a second level of referencing to access concepts in the the maps.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <C> the type of concept on which the interface is applied.
+ */
+public interface AxConceptGetter<C> {
+
+ /**
+ * Get the latest version for a concept with the given key.
+ *
+ * @param conceptKey The key of the concept
+ * @return The concept
+ */
+ C get(AxArtifactKey conceptKey);
+
+ /**
+ * Get the latest version for a concept with the given key name.
+ *
+ * @param conceptKeyName The name of the concept
+ * @return The concept
+ */
+ C get(String conceptKeyName);
+
+ /**
+ * Get the latest version for a concept with the given key name and version.
+ *
+ * @param conceptKeyName The name of the concept
+ * @param conceptKeyVersion The version of the concept
+ * @return The concept
+ */
+ C get(String conceptKeyName, String conceptKeyVersion);
+
+ /**
+ * Get the all versions for a concept with the given key name.
+ *
+ * @param conceptKeyName The name of the concept
+ * @return The concepts
+ */
+ Set<C> getAll(String conceptKeyName);
+
+ /**
+ * Get the all versions for a concept with the given key name and starting version.
+ *
+ * @param conceptKeyName The name of the concept
+ * @param conceptKeyVersion The first version version of the concept to get
+ * @return The concepts
+ */
+ Set<C> getAll(String conceptKeyName, String conceptKeyVersion);
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetterImpl.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetterImpl.java
new file mode 100644
index 000000000..9c907da9c
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetterImpl.java
@@ -0,0 +1,143 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2021 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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeSet;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * Implements concept getting from navigable maps.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <C> the type of concept on which the interface implementation is applied.
+ */
+public class AxConceptGetterImpl<C> implements AxConceptGetter<C> {
+
+ // The map from which to get concepts
+ private final NavigableMap<AxArtifactKey, C> conceptMap;
+
+ /**
+ * Constructor that sets the concept map on which the getter methods in the interface will operate..
+ *
+ * @param conceptMap the concept map on which the method will operate
+ */
+ public AxConceptGetterImpl(final NavigableMap<AxArtifactKey, C> conceptMap) {
+ this.conceptMap = conceptMap;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public C get(final AxArtifactKey conceptKey) {
+ return conceptMap.get(conceptKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public C get(final String conceptKeyName) {
+ Assertions.argumentNotNull(conceptKeyName, "conceptKeyName may not be null");
+
+ // The very fist key that could have this name
+ final var lowestArtifactKey = new AxArtifactKey(conceptKeyName, "0.0.1");
+
+ // Check if we found a key for our name
+ AxArtifactKey foundKey = conceptMap.ceilingKey(lowestArtifactKey);
+ if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) {
+ return null;
+ }
+
+ // Look for higher versions of the key
+ do {
+ final AxArtifactKey nextkey = conceptMap.higherKey(foundKey);
+ if (nextkey == null || !nextkey.getName().equals(conceptKeyName)) {
+ break;
+ }
+ foundKey = nextkey;
+ } while (true);
+
+ return conceptMap.get(foundKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public C get(final String conceptKeyName, final String conceptKeyVersion) {
+ Assertions.argumentNotNull(conceptKeyName, "conceptKeyName may not be null");
+
+ if (conceptKeyVersion != null) {
+ return conceptMap.get(new AxArtifactKey(conceptKeyName, conceptKeyVersion));
+ } else {
+ return this.get(conceptKeyName);
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<C> getAll(final String conceptKeyName) {
+ return getAll(conceptKeyName, null);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<C> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ final Set<C> returnSet = new TreeSet<>();
+
+ if (conceptKeyName == null) {
+ returnSet.addAll(conceptMap.values());
+ return returnSet;
+ }
+
+ // The very fist key that could have this name
+ final var lowestArtifactKey = new AxArtifactKey(conceptKeyName, "0.0.1");
+ if (conceptKeyVersion != null) {
+ lowestArtifactKey.setVersion(conceptKeyVersion);
+ }
+
+ // Check if we found a key for our name
+ AxArtifactKey foundKey = conceptMap.ceilingKey(lowestArtifactKey);
+ if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) {
+ return returnSet;
+ }
+ returnSet.add(conceptMap.get(foundKey));
+
+ // Look for higher versions of the key
+ do {
+ foundKey = conceptMap.higherKey(foundKey);
+ if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) {
+ break;
+ }
+ returnSet.add(conceptMap.get(foundKey));
+ } while (true);
+
+ return returnSet;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKey.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKey.java
new file mode 100644
index 000000000..1b6f0148f
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKey.java
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+/**
+ * The key uniquely identifies every entity in the system. This class is an abstract class to give a common parent for
+ * all key types in the system.
+ */
+public abstract class AxKey extends AxConcept {
+ private static final long serialVersionUID = 6281159885962014041L;
+
+ /** Regular expression to specify the structure of key names. */
+ public static final String NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+";
+
+ /** Regular expression to specify the structure of key versions. */
+ public static final String VERSION_REGEXP = "[A-Za-z0-9.]+";
+
+ /** Regular expression to specify the structure of key IDs. */
+ public static final String KEY_ID_REGEXP = "[A-Za-z0-9\\-_\\.]+:[0-9].[0-9].[0-9]";
+
+ /** Specifies the value for names in NULL keys. */
+ public static final String NULL_KEY_NAME = "NULL";
+
+ /** Specifies the value for versions in NULL keys. */
+ public static final String NULL_KEY_VERSION = "0.0.0";
+
+ /**
+ * This enumeration is returned on key compatibility checks.
+ */
+ public enum Compatibility {
+ /** The keys have different names. */
+ DIFFERENT,
+ /**
+ * The name of the key matches but the Major version number of the keys is different (x in x.y.z do not match).
+ */
+ MAJOR,
+ /**
+ * The name of the key matches but the Minor version number of the keys is different (y in x.y.z do not match).
+ */
+ MINOR,
+ /**
+ * The name of the key matches but the Patch version number of the keys is different (z in x.y.z do not match).
+ */
+ PATCH,
+ /** The keys match completely. */
+ IDENTICAL
+ }
+
+ /**
+ * Default constructor.
+ */
+ protected AxKey() {
+ super();
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ protected AxKey(final AxKey copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public abstract String getId();
+
+ /**
+ * Return the result of a compatibility check of two keys.
+ *
+ * @param otherKey the key to check compatibility against
+ * @return the compatibility result of the check
+ */
+ public abstract Compatibility getCompatibility(AxKey otherKey);
+
+ /**
+ * Check if two keys are compatible, that is the keys are IDENTICAL or have only MINOR, PATCH differences.
+ *
+ * @param otherKey the key to check compatibility against
+ * @return true, if the keys are compatible
+ */
+ public abstract boolean isCompatible(AxKey otherKey);
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfo.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfo.java
new file mode 100644
index 000000000..bd3b18ec9
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfo.java
@@ -0,0 +1,317 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+import com.google.gson.annotations.SerializedName;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * The key information on an {@link AxArtifactKey} key in an Apex policy model. Each {@link AxArtifactKey} must have an
+ * {@link AxKeyInfo} object. THe information held is the key's UUID and it's description.
+ *
+ * <p>Validation checks that all fields are defined and that the key is valid. It also observes that descriptions are
+ * blank and warns if the UUID is a zero UUID.
+ */
+public class AxKeyInfo extends AxConcept {
+ private static final long serialVersionUID = -4023935924068914308L;
+
+ private static final int UUID_BYTE_LENGTH_16 = 16;
+
+ /*
+ * This is not used for encryption/security, thus disabling sonar.
+ */
+ private static final Random sharedRandom = new Random(); // NOSONAR
+
+ private AxArtifactKey key;
+
+ @SerializedName("UUID")
+ private UUID uuid;
+
+ private String description;
+
+ /**
+ * The Default Constructor creates this concept with a NULL artifact key.
+ */
+ public AxKeyInfo() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxKeyInfo(final AxKeyInfo copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor to create this concept with the specified key.
+ *
+ * @param key the key of the concept
+ */
+ public AxKeyInfo(final AxArtifactKey key) {
+ this(key, UUID.randomUUID(), "Generated description for concept referred to by key \"" + key.getId() + "\"");
+ }
+
+ /**
+ * Constructor to create this concept and set all its fields.
+ *
+ * @param key the key of the concept
+ * @param uuid the UUID of the concept
+ * @param description the description of the concept
+ */
+ public AxKeyInfo(final AxArtifactKey key, final UUID uuid, final String description) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(uuid, "uuid may not be null");
+ Assertions.argumentNotNull(description, "description may not be null");
+
+ this.key = key;
+ this.uuid = uuid;
+ this.description = description.trim();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return key.getKeys();
+ }
+
+ /**
+ * Sets the key of the concept.
+ *
+ * @param key the concept key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the UUID of the concept.
+ *
+ * @return the uuid of the concept
+ */
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ /**
+ * Sets the UUID of the concept.
+ *
+ * @param uuid the uuid of the concept
+ */
+ public void setUuid(final UUID uuid) {
+ Assertions.argumentNotNull(uuid, "uuid may not be null");
+ this.uuid = uuid;
+ }
+
+ /**
+ * Gets the description of the concept.
+ *
+ * @return the description of the concept
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Sets the description of the concept.
+ *
+ * @param description the description of the concept
+ */
+ public void setDescription(final String description) {
+ Assertions.argumentNotNull(description, "description may not be null");
+ this.description = description.trim();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (description.trim().length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "description is blank"));
+ }
+
+ if (uuid.equals(new UUID(0, 0))) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.WARNING,
+ "UUID is a zero UUID: " + new UUID(0, 0)));
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ description = description.trim();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final var builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("artifactId=");
+ builder.append(key);
+ builder.append(",uuid=");
+ builder.append(uuid);
+ builder.append(",description=");
+ builder.append(description);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxKeyInfo.class);
+
+ final AxKeyInfo copy = ((AxKeyInfo) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setUuid(UUID.fromString(uuid.toString()));
+ copy.setDescription(description);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final var prime = 31;
+ var result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + uuid.hashCode();
+ result = prime * result + description.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxKeyInfo other = (AxKeyInfo) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!uuid.equals(other.uuid)) {
+ return false;
+ }
+ return description.equals(description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxKeyInfo other = (AxKeyInfo) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!uuid.equals(other.uuid)) {
+ return uuid.compareTo(other.uuid);
+ }
+ return description.compareTo(other.description);
+ }
+
+ /**
+ * Generate a reproducible UUID for a given string seed.
+ *
+ * @param seed the seed
+ * @return the uuid
+ */
+ public static UUID generateReproducibleUuid(final String seed) {
+ var random = sharedRandom;
+ if (!StringUtils.isEmpty(seed)) {
+ /*
+ * This is not used for encryption/security, thus disabling sonar.
+ */
+ random = new Random(seed.hashCode()); // NOSONAR
+ }
+ final var array = new byte[UUID_BYTE_LENGTH_16];
+ random.nextBytes(array);
+ return UUID.nameUUIDFromBytes(array);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInformation.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInformation.java
new file mode 100644
index 000000000..439b2960f
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInformation.java
@@ -0,0 +1,389 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.UUID;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * The Class AxKeyInformation holds a map of the key information for the entire Apex model. All Apex models
+ * {@link AxModel} must have an {@link AxKeyInformation} field. The {@link AxKeyInformation} class implements the helper
+ * methods of the {@link AxConceptGetter} interface to allow {@link AxKeyInfo} instances to be retrieved by calling
+ * methods directly on this class without referencing the contained map.
+ *
+ * <p>Validation checks that the key is not null, that the key information map is not empty, that each key and value in
+ * the map is defined, that the key in each map entry matches the key if each entry value, and that no duplicate UUIDs
+ * exist. Each key information entry is then validated individually.
+ */
+public class AxKeyInformation extends AxConcept implements AxConceptGetter<AxKeyInfo> {
+ private static final long serialVersionUID = -2746380769017043888L;
+
+ private AxArtifactKey key;
+ private Map<AxArtifactKey, AxKeyInfo> keyInfoMap;
+
+ /**
+ * The Default Constructor creates this concept with a null key.
+ */
+ public AxKeyInformation() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxKeyInformation(final AxKeyInformation copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor to create this concept with the specified key.
+ *
+ * @param key the key of the concept
+ */
+ public AxKeyInformation(final AxArtifactKey key) {
+ this(key, new TreeMap<>());
+ }
+
+ /**
+ * Constructor to create this concept and set all its fields.
+ *
+ * @param key the key of the concept
+ * @param keyInfoMap the key info map of the concept
+ */
+ public AxKeyInformation(final AxArtifactKey key, final Map<AxArtifactKey, AxKeyInfo> keyInfoMap) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(keyInfoMap, "keyInfoMap may not be null");
+
+ this.key = key;
+ this.keyInfoMap = new TreeMap<>();
+ this.keyInfoMap.putAll(keyInfoMap);
+ }
+
+ /**
+ * This method generates default key information for all keys found in the concept passed in as a parameter that do
+ * not already have key information.
+ *
+ * @param concept the concept for which to generate key information
+ */
+ public void generateKeyInfo(final AxConcept concept) {
+ for (final AxKey axKey : concept.getKeys()) {
+ if (!(axKey instanceof AxArtifactKey)) {
+ continue;
+ }
+
+ final AxArtifactKey artifactKey = (AxArtifactKey) axKey;
+
+ keyInfoMap.computeIfAbsent(artifactKey, unusedKey -> {
+ final var keyInfo = new AxKeyInfo(artifactKey);
+ // generate a reproducible UUID
+ keyInfo.setUuid(AxKeyInfo.generateReproducibleUuid(keyInfo.getId() + keyInfo.getDescription()));
+ return keyInfo;
+ });
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.addAll(keyInfoMap.keySet());
+
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void buildReferences() {
+ keyInfoMap.values().stream().forEach(keyInfo -> keyInfo.buildReferences());
+ }
+
+ /**
+ * Sets the key of this concept.
+ *
+ * @param key the key of this concept
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the key info map of this concept.
+ *
+ * @return the key info map of this concept
+ */
+ public Map<AxArtifactKey, AxKeyInfo> getKeyInfoMap() {
+ return keyInfoMap;
+ }
+
+ /**
+ * Sets the key info map of this concept.
+ *
+ * @param keyInfoMap the key info map of this concept
+ */
+ public void setKeyInfoMap(final Map<AxArtifactKey, AxKeyInfo> keyInfoMap) {
+ Assertions.argumentNotNull(keyInfoMap, "keyInfoMap may not be null");
+ this.keyInfoMap = new TreeMap<>();
+ this.keyInfoMap.putAll(keyInfoMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (keyInfoMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "keyInfoMap may not be empty"));
+ } else {
+ final Set<UUID> uuidSet = new TreeSet<>();
+
+ for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry : keyInfoMap.entrySet()) {
+ result = validateKeyInfoEntry(keyInfoEntry, uuidSet, result);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate a key information entry.
+ *
+ * @param keyInfoEntry the key information entry
+ * @param uuidSet the set of UUIDs encountered in validation so far, the UUID of this entry is added to the set
+ * @param result the validation result to append to
+ * @return The validation result
+ */
+ private AxValidationResult validateKeyInfoEntry(final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry,
+ final Set<UUID> uuidSet, AxValidationResult result) {
+ if (keyInfoEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on keyInfoMap entry " + keyInfoEntry.getKey() + " may not be the null key"));
+ } else if (keyInfoEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on keyInfoMap entry " + keyInfoEntry.getKey() + " may not be null"));
+ } else {
+ if (!keyInfoEntry.getKey().equals(keyInfoEntry.getValue().getKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on keyInfoMap entry " + keyInfoEntry.getKey() + " does not equal entry key "
+ + keyInfoEntry.getValue().getKey()));
+ }
+
+ result = keyInfoEntry.getValue().validate(result);
+
+ if (uuidSet.contains(keyInfoEntry.getValue().getUuid())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "duplicate UUID found on keyInfoMap entry " + keyInfoEntry.getKey() + ":"
+ + keyInfoEntry.getValue().getUuid()));
+ } else {
+ uuidSet.add(keyInfoEntry.getValue().getUuid());
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry : keyInfoMap.entrySet()) {
+ keyInfoEntry.getKey().clean();
+ keyInfoEntry.getValue().clean();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final var builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",keyInfoMap=");
+ builder.append(keyInfoMap);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxKeyInformation.class);
+
+ final AxKeyInformation copy = ((AxKeyInformation) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ final Map<AxArtifactKey, AxKeyInfo> newKeyInfoMap = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoMapEntry : keyInfoMap.entrySet()) {
+ newKeyInfoMap.put(new AxArtifactKey(keyInfoMapEntry.getKey()), new AxKeyInfo(keyInfoMapEntry.getValue()));
+ }
+ copy.setKeyInfoMap(newKeyInfoMap);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final var prime = 31;
+ var result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + keyInfoMap.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxKeyInformation other = (AxKeyInformation) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return keyInfoMap.equals(other.keyInfoMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxKeyInformation other = (AxKeyInformation) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!keyInfoMap.equals(other.keyInfoMap)) {
+ return (keyInfoMap.hashCode() - other.keyInfoMap.hashCode());
+ }
+
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxKeyInfo get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxKeyInfo get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxKeyInfo get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxKeyInfo> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).getAll(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxKeyInfo> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyUse.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyUse.java
new file mode 100644
index 000000000..eb701e5b3
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyUse.java
@@ -0,0 +1,221 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2021 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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class records a usage of a key in the system. When the list of keys being used by a concept is built using the
+ * getKeys() method of the {@link AxConcept} class, an instance of this class is created for every key occurrence. The
+ * list of keys returned by the getKeys() method is a list of {@link AxKeyUse} objects.
+ *
+ * <p>Validation checks that each key is valid.
+ */
+
+public class AxKeyUse extends AxKey {
+ private static final long serialVersionUID = 2007147220109881705L;
+
+ private AxKey usedKey;
+
+ /**
+ * The Default Constructor creates this concept with a null key.
+ */
+ public AxKeyUse() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxKeyUse(final AxKeyUse copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * This constructor creates an instance of this class, and holds a reference to a used key.
+ *
+ * @param usedKey a used key
+ */
+ public AxKeyUse(final AxKey usedKey) {
+ Assertions.argumentNotNull(usedKey, "usedKey may not be null");
+ this.usedKey = usedKey;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxKey getKey() {
+ return usedKey;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return usedKey.getKeys();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getId() {
+ return usedKey.getId();
+ }
+
+ /**
+ * Sets the key.
+ *
+ * @param key the key
+ */
+ public void setKey(final AxKey key) {
+ Assertions.argumentNotNull(key, "usedKey may not be null");
+ this.usedKey = key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxKey.Compatibility getCompatibility(final AxKey otherKey) {
+ return usedKey.getCompatibility(otherKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean isCompatible(final AxKey otherKey) {
+ return usedKey.isCompatible(otherKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult result) {
+ if (usedKey.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(usedKey, this.getClass(), ValidationResult.INVALID,
+ "usedKey is a null key"));
+ }
+ return usedKey.validate(result);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ usedKey.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final var builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("usedKey=");
+ builder.append(usedKey);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxKeyUse.class);
+
+ final AxKeyUse copy = ((AxKeyUse) copyObject);
+ try {
+ copy.usedKey = usedKey.getClass().getDeclaredConstructor().newInstance();
+ } catch (final Exception e) {
+ throw new ApexRuntimeException("error copying concept key: " + e.getMessage(), e);
+ }
+ usedKey.copyTo(copy.usedKey);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final var prime = 31;
+ var result = 1;
+ result = prime * result + usedKey.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ throw new IllegalArgumentException("comparison object may not be null");
+ }
+
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxKeyUse other = (AxKeyUse) obj;
+ return usedKey.equals(other.usedKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxKeyUse other = (AxKeyUse) otherObj;
+
+ return usedKey.compareTo(other.usedKey);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxModel.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxModel.java
new file mode 100644
index 000000000..ce52b147f
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxModel.java
@@ -0,0 +1,423 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is the base class for all models in Apex. All model classes inherit from this model so all models must
+ * have a key and have key information.
+ *
+ * <p>Validation checks that the model key is valid. It goes on to check for null keys and checks each key for
+ * uniqueness in the model. A check is carried out to ensure that an {@link AxKeyInfo} instance exists for every
+ * {@link AxArtifactKey} key. For each {@link AxReferenceKey} instance, a check is made that its parent and local name
+ * are nut null and that a {@link AxKeyInfo} entry exists for its parent. Then a check is made that each used
+ * {@link AxArtifactKey} and {@link AxReferenceKey} usage references a key that exists. Finally, a check is made to
+ * ensure that an {@link AxArtifactKey} instance exists for every {@link AxKeyInfo} instance.
+ */
+public class AxModel extends AxConcept {
+ private static final String IS_A_NULL_KEY = " is a null key";
+
+ private static final long serialVersionUID = -771659065637205430L;
+
+ private AxArtifactKey key;
+ private AxKeyInformation keyInformation;
+
+ /**
+ * The Default Constructor creates this concept with a NULL artifact key.
+ */
+ public AxModel() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxModel(final AxModel copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor to create this concept with the specified key.
+ *
+ * @param key the key of this concept
+ */
+ public AxModel(final AxArtifactKey key) {
+ this(key, new AxKeyInformation(new AxArtifactKey(key.getName() + "_KeyInfo", key.getVersion())));
+ }
+
+ /**
+ * Constructor to create this concept and set all its fields.
+ *
+ * @param key the key of this concept
+ * @param keyInformation the key information of this concept
+ */
+ public AxModel(final AxArtifactKey key, final AxKeyInformation keyInformation) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(keyInformation, "keyInformation may not be null");
+
+ this.key = key;
+ this.keyInformation = keyInformation;
+ }
+
+ /**
+ * Registers this model with the {@link ModelService}. All models are registered with the model service so that
+ * models can be references from anywhere in the Apex system without being passed as references through deep call
+ * chains.
+ */
+ public void register() {
+ ModelService.registerModel(AxKeyInformation.class, getKeyInformation());
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ // We just add the key for the KeyInformation itself. We don't add the
+ // keys from key information because
+ // that is a list of key information for existing keys
+ keyList.add(keyInformation.getKey());
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of this concept.
+ *
+ * @param key the key of this concept
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the key information of this concept.
+ *
+ * @return the key information of this concept
+ */
+ public AxKeyInformation getKeyInformation() {
+ return keyInformation;
+ }
+
+ /**
+ * Sets the key information of this concept.
+ *
+ * @param keyInformation the key information of this concept
+ */
+ public void setKeyInformation(final AxKeyInformation keyInformation) {
+ Assertions.argumentNotNull(keyInformation, "keyInformation may not be null");
+ this.keyInformation = keyInformation;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+ result = keyInformation.validate(result);
+
+ // Key consistency check
+ final Set<AxArtifactKey> artifactKeySet = new TreeSet<>();
+ final Set<AxReferenceKey> referenceKeySet = new TreeSet<>();
+ final Set<AxKeyUse> usedKeySet = new TreeSet<>();
+
+ for (final AxKey axKey : this.getKeys()) {
+ // Check for the two type of keys we have
+ if (axKey instanceof AxArtifactKey) {
+ result = validateArtifactKeyInModel((AxArtifactKey) axKey, artifactKeySet, result);
+ } else if (axKey instanceof AxReferenceKey) {
+ result = validateReferenceKeyInModel((AxReferenceKey) axKey, referenceKeySet, result);
+ } else {
+ // It must be an AxKeyUse, nothing else is legal
+ usedKeySet.add((AxKeyUse) axKey);
+ }
+ }
+
+ // Check all reference keys have correct parent keys
+ for (final AxReferenceKey referenceKey : referenceKeySet) {
+ if (!artifactKeySet.contains(referenceKey.getParentArtifactKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent artifact key not found for reference key " + referenceKey));
+ }
+ }
+
+ result = validateKeyUses(usedKeySet, artifactKeySet, referenceKeySet, result);
+
+ // Check key information for unused key information
+ for (final AxArtifactKey keyInfoKey : keyInformation.getKeyInfoMap().keySet()) {
+ if (!artifactKeySet.contains(keyInfoKey)) {
+ result.addValidationMessage(new AxValidationMessage(keyInfoKey, this.getClass(),
+ ValidationResult.WARNING, "key not found for key information entry"));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Check for consistent usage of an artifact key in the model.
+ *
+ * @param artifactKey The artifact key to check
+ * @param artifactKeySet The set of artifact keys encountered so far, this key is appended to the set
+ * @param result The validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateArtifactKeyInModel(final AxArtifactKey artifactKey,
+ final Set<AxArtifactKey> artifactKeySet, final AxValidationResult result) {
+ // Null key check
+ if (artifactKey.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key " + artifactKey + IS_A_NULL_KEY));
+ }
+
+ // Null key name start check
+ if (artifactKey.getName().toUpperCase().startsWith(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key " + artifactKey + " name starts with keyword " + AxKey.NULL_KEY_NAME));
+ }
+
+ // Unique key check
+ if (artifactKeySet.contains(artifactKey)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "duplicate key " + artifactKey + " found"));
+ } else {
+ artifactKeySet.add(artifactKey);
+ }
+
+ // Key information check
+ if (!keyInformation.getKeyInfoMap().containsKey(artifactKey)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key information not found for key " + artifactKey));
+ }
+
+ return result;
+ }
+
+ /**
+ * Check for consistent usage of a reference key in the model.
+ *
+ * @param referenceKey The reference key to check
+ * @param referenceKeySet The set of reference keys encountered so far, this key is appended to the set
+ * @param result The validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateReferenceKeyInModel(final AxReferenceKey referenceKey,
+ final Set<AxReferenceKey> referenceKeySet, final AxValidationResult result) {
+ // Null key check
+ if (referenceKey.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key " + referenceKey + IS_A_NULL_KEY));
+ }
+
+ // Null parent key check
+ if (referenceKey.getParentArtifactKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent artifact key of key " + referenceKey + IS_A_NULL_KEY));
+ }
+
+ // Null local name check
+ if (referenceKey.getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key " + referenceKey + " has a null local name"));
+ }
+
+ // Null key name start check
+ if (referenceKey.getParentArtifactKey().getName().toUpperCase().startsWith(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key " + referenceKey + " parent name starts with keyword " + AxKey.NULL_KEY_NAME));
+ }
+
+ // Unique key check
+ if (referenceKeySet.contains(referenceKey)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "duplicate key " + referenceKey + " found"));
+ } else {
+ referenceKeySet.add(referenceKey);
+ }
+
+ // Key information check
+ if (!keyInformation.getKeyInfoMap().containsKey(referenceKey.getParentArtifactKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key information not found for parent key of key " + referenceKey));
+ }
+
+ return result;
+ }
+
+ /**
+ * Check for consistent usage of cross-key references in the model.
+ *
+ * @param usedKeySet The set of all keys used in the model
+ * @param artifactKeySet The set of artifact keys encountered so far, this key is appended to the set
+ * @param referenceKeySet The set of reference keys encountered so far, this key is appended to the set
+ * @param result The validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateKeyUses(final Set<AxKeyUse> usedKeySet, final Set<AxArtifactKey> artifactKeySet,
+ final Set<AxReferenceKey> referenceKeySet, final AxValidationResult result) {
+ // Check all key uses
+ for (final AxKeyUse usedKey : usedKeySet) {
+ if (usedKey.getKey() instanceof AxArtifactKey) {
+ // AxArtifact key usage, check the key exists
+ if (!artifactKeySet.contains(usedKey.getKey())) {
+ result.addValidationMessage(new AxValidationMessage(usedKey.getKey(), this.getClass(),
+ ValidationResult.INVALID, "an artifact key used in the model is not defined"));
+ }
+ } else {
+ // AxReference key usage, check the key exists
+ if (!referenceKeySet.contains(usedKey.getKey())) {
+ result.addValidationMessage(new AxValidationMessage(usedKey.getKey(), this.getClass(),
+ ValidationResult.INVALID, "a reference key used in the model is not defined"));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ keyInformation.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final var builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",keyInformation=");
+ builder.append(keyInformation);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxModel.class);
+
+ final AxModel copy = ((AxModel) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setKeyInformation(new AxKeyInformation(keyInformation));
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final var prime = 31;
+ var result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + keyInformation.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxModel other = (AxModel) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return keyInformation.equals(other.keyInformation);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxModel other = (AxModel) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ return keyInformation.compareTo(other.keyInformation);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxReferenceKey.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxReferenceKey.java
new file mode 100644
index 000000000..b37bc47e4
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxReferenceKey.java
@@ -0,0 +1,527 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * A reference key identifies entities in the system that are contained in other entities. Every contained concept in
+ * the system must have an {@link AxReferenceKey} to identify it. Non-contained first order concepts are identified
+ * using an {@link AxArtifactKey} key.
+ *
+ * <p>An {@link AxReferenceKey} contains an {@link AxArtifactKey} key reference to the first order entity that contains
+ * it. The local name of the reference key must uniquely identify the referenced concept among those concepts contained
+ * in the reference key's parent. In other words, if a parent concept has more than one child, the local name in the key
+ * of all its children must be unique.
+ *
+ * <p>If a reference key's parent is itself a reference key, then the parent's local name must be set in the reference
+ * key. If the parent is a first order concept, then the parent's local name in the key will be set to NULL.
+ *
+ * <p>Key validation checks that the parent name and parent version fields match the NAME_REGEXP and
+ * VERSION_REGEXP regular expressions respectively and that the local name fields match the
+ * LOCAL_NAME_REGEXP regular expression.
+ */
+public class AxReferenceKey extends AxKey {
+ private static final String PARENT_KEY_NAME = "parentKeyName";
+ private static final String PARENT_KEY_VERSION = "parentKeyVersion";
+ private static final String PARENT_LOCAL_NAME = "parentLocalName";
+ private static final String LOCAL_NAME = "localName";
+
+ private static final long serialVersionUID = 8932717618579392561L;
+
+ /**
+ * Regular expression to specify the structure of local names in reference keys.
+ */
+ public static final String LOCAL_NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+|^$";
+
+ /**
+ * Regular expression to specify the structure of IDs in reference keys.
+ */
+ public static final String REFERENCE_KEY_ID_REGEXP =
+ "[A-Za-z0-9\\-_]+:[0-9].[0-9].[0-9]:[A-Za-z0-9\\-_]+:[A-Za-z0-9\\-_]+";
+
+ private static final int PARENT_NAME_FIELD = 0;
+ private static final int PARENT_VERSION_FIELD = 1;
+ private static final int PARENT_LOCAL_NAME_FIELD = 2;
+ private static final int LOCAL_NAME_FIELD = 3;
+
+ private String parentKeyName;
+ private String parentKeyVersion;
+ private String parentLocalName;
+ private String localName;
+
+ /**
+ * The default constructor creates a null reference key.
+ */
+ public AxReferenceKey() {
+ this(NULL_KEY_NAME, NULL_KEY_VERSION, NULL_KEY_NAME, NULL_KEY_NAME);
+ }
+
+ /**
+ * The Copy Constructor creates a key by copying another key.
+ *
+ * @param referenceKey the reference key to copy from
+ */
+ public AxReferenceKey(final AxReferenceKey referenceKey) {
+ this(referenceKey.getParentKeyName(), referenceKey.getParentKeyVersion(), referenceKey.getParentLocalName(),
+ referenceKey.getLocalName());
+ }
+
+ /**
+ * Constructor to create a null reference key for the specified parent artifact key.
+ *
+ * @param axArtifactKey the parent artifact key of this reference key
+ */
+ public AxReferenceKey(final AxArtifactKey axArtifactKey) {
+ this(axArtifactKey.getName(), axArtifactKey.getVersion(), NULL_KEY_NAME, NULL_KEY_NAME);
+ }
+
+ /**
+ * Constructor to create a reference key for the given parent artifact key with the given local name.
+ *
+ * @param axArtifactKey the parent artifact key of this reference key
+ * @param localName the local name of this reference key
+ */
+ public AxReferenceKey(final AxArtifactKey axArtifactKey, final String localName) {
+ this(axArtifactKey, NULL_KEY_NAME, localName);
+ }
+
+ /**
+ * Constructor to create a reference key for the given parent reference key with the given local name.
+ *
+ * @param parentReferenceKey the parent reference key of this reference key
+ * @param localName the local name of this reference key
+ */
+ public AxReferenceKey(final AxReferenceKey parentReferenceKey, final String localName) {
+ this(parentReferenceKey.getParentArtifactKey(), parentReferenceKey.getLocalName(), localName);
+ }
+
+ /**
+ * Constructor to create a reference key for the given parent reference key (specified by the parent reference key's
+ * artifact key and local name) with the given local name.
+ *
+ * @param axArtifactKey the artifact key of the parent reference key of this reference key
+ * @param parentLocalName the local name of the parent reference key of this reference key
+ * @param localName the local name of this reference key
+ */
+ public AxReferenceKey(final AxArtifactKey axArtifactKey, final String parentLocalName, final String localName) {
+ this(axArtifactKey.getName(), axArtifactKey.getVersion(), parentLocalName, localName);
+ }
+
+ /**
+ * Constructor to create a reference key for the given parent artifact key (specified by the parent artifact key's
+ * name and version) with the given local name.
+ *
+ * @param parentKeyName the name of the parent artifact key of this reference key
+ * @param parentKeyVersion the version of the parent artifact key of this reference key
+ * @param localName the local name of this reference key
+ */
+ public AxReferenceKey(final String parentKeyName, final String parentKeyVersion, final String localName) {
+ this(parentKeyName, parentKeyVersion, NULL_KEY_NAME, localName);
+ }
+
+ /**
+ * Constructor to create a reference key for the given parent key (specified by the parent key's name, version nad
+ * local name) with the given local name.
+ *
+ * @param parentKeyName the parent key name of this reference key
+ * @param parentKeyVersion the parent key version of this reference key
+ * @param parentLocalName the parent local name of this reference key
+ * @param localName the local name of this reference key
+ */
+ public AxReferenceKey(final String parentKeyName, final String parentKeyVersion, final String parentLocalName,
+ final String localName) {
+ super();
+ this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
+ this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion,
+ VERSION_REGEXP);
+ this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName,
+ LOCAL_NAME_REGEXP);
+ this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
+ }
+
+ /**
+ * Constructor to create a key from the specified key ID.
+ *
+ * @param id the key ID in a format that respects the KEY_ID_REGEXP
+ */
+ public AxReferenceKey(final String id) {
+ final var conditionedId = Assertions.validateStringParameter("id", id, REFERENCE_KEY_ID_REGEXP);
+
+ // Split on colon, if the id passes the regular expression test above
+ // it'll have just three colons separating the parent name,
+ // parent version, parent local name, and and local name
+ // No need for range checks or size checks on the array
+ final String[] nameVersionNameArray = conditionedId.split(":");
+
+ // Initiate the new key
+ parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, nameVersionNameArray[PARENT_NAME_FIELD],
+ NAME_REGEXP);
+ parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION,
+ nameVersionNameArray[PARENT_VERSION_FIELD], VERSION_REGEXP);
+ parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME,
+ nameVersionNameArray[PARENT_LOCAL_NAME_FIELD], LOCAL_NAME_REGEXP);
+ localName = Assertions.validateStringParameter(LOCAL_NAME, nameVersionNameArray[LOCAL_NAME_FIELD],
+ LOCAL_NAME_REGEXP);
+ }
+
+ /**
+ * Get a null reference key.
+ *
+ * @return a null reference key
+ */
+ public static AxReferenceKey getNullKey() {
+ return new AxReferenceKey(AxKey.NULL_KEY_NAME, AxKey.NULL_KEY_VERSION, AxKey.NULL_KEY_NAME,
+ AxKey.NULL_KEY_NAME);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = new ArrayList<>();
+ keyList.add(getKey());
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getId() {
+ return parentKeyName + ':' + parentKeyVersion + ':' + parentLocalName + ':' + localName;
+ }
+
+ /**
+ * Gets the parent artifact key of this reference key.
+ *
+ * @return the parent artifact key of this reference key
+ */
+ public AxArtifactKey getParentArtifactKey() {
+ return new AxArtifactKey(parentKeyName, parentKeyVersion);
+ }
+
+ /**
+ * Gets the parent reference key of this reference key.
+ *
+ * @return the parent reference key of this reference key
+ */
+ public AxReferenceKey getParentReferenceKey() {
+ return new AxReferenceKey(parentKeyName, parentKeyVersion, parentLocalName);
+ }
+
+ /**
+ * Sets the parent artifact key of this reference key.
+ *
+ * @param parentKey the parent artifact key of this reference key
+ */
+ public void setParentArtifactKey(final AxArtifactKey parentKey) {
+ Assertions.argumentNotNull(parentKey, "parentKey may not be null");
+
+ parentKeyName = parentKey.getName();
+ parentKeyVersion = parentKey.getVersion();
+ parentLocalName = NULL_KEY_NAME;
+ }
+
+ /**
+ * Sets the parent reference key of this reference key.
+ *
+ * @param parentKey the parent reference key of this reference key
+ */
+ public void setParentReferenceKey(final AxReferenceKey parentKey) {
+ Assertions.argumentNotNull(parentKey, "parentKey may not be null");
+
+ parentKeyName = parentKey.getParentKeyName();
+ parentKeyVersion = parentKey.getParentKeyVersion();
+ parentLocalName = parentKey.getLocalName();
+ }
+
+ /**
+ * Gets the parent key name of this reference key.
+ *
+ * @return the parent key name of this reference key
+ */
+ public String getParentKeyName() {
+ return parentKeyName;
+ }
+
+ /**
+ * Sets the parent key name of this reference key.
+ *
+ * @param parentKeyName the parent key name of this reference key
+ */
+ public void setParentKeyName(final String parentKeyName) {
+ this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
+ }
+
+ /**
+ * Gets the parent key version of this reference key.
+ *
+ * @return the parent key version of this reference key
+ */
+ public String getParentKeyVersion() {
+ return parentKeyVersion;
+ }
+
+ /**
+ * Sets the parent key version of this reference key.
+ *
+ * @param parentKeyVersion the parent key version of this reference key
+ */
+ public void setParentKeyVersion(final String parentKeyVersion) {
+ this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion,
+ VERSION_REGEXP);
+ }
+
+ /**
+ * Gets the parent local name of this reference key.
+ *
+ * @return the parent local name of this reference key
+ */
+ public String getParentLocalName() {
+ return parentLocalName;
+ }
+
+ /**
+ * Sets the parent local name of this reference key.
+ *
+ * @param parentLocalName the parent local name of this reference key
+ */
+ public void setParentLocalName(final String parentLocalName) {
+ this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName,
+ LOCAL_NAME_REGEXP);
+ }
+
+ /**
+ * Gets the local name of this reference key.
+ *
+ * @return the local name of this reference key
+ */
+ public String getLocalName() {
+ return localName;
+ }
+
+ /**
+ * Sets the local name of this reference key.
+ *
+ * @param localName the local name of this reference key
+ */
+ public void setLocalName(final String localName) {
+ this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxKey.Compatibility getCompatibility(final AxKey otherKey) {
+ if (!(otherKey instanceof AxReferenceKey)) {
+ return Compatibility.DIFFERENT;
+ }
+ final AxReferenceKey otherReferenceKey = (AxReferenceKey) otherKey;
+
+ return this.getParentArtifactKey().getCompatibility(otherReferenceKey.getParentArtifactKey());
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean isCompatible(final AxKey otherKey) {
+ if (!(otherKey instanceof AxReferenceKey)) {
+ return false;
+ }
+ final AxReferenceKey otherReferenceKey = (AxReferenceKey) otherKey;
+
+ return this.getParentArtifactKey().isCompatible(otherReferenceKey.getParentArtifactKey());
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult result) {
+ final var parentNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(PARENT_KEY_NAME,
+ parentKeyName, NAME_REGEXP);
+ if (parentNameValidationErrorMessage != null) {
+ result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+ "parentKeyName invalid-" + parentNameValidationErrorMessage));
+ }
+
+ final var parentKeyVersionValidationErrorMessage = Assertions
+ .getStringParameterValidationMessage(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
+ if (parentKeyVersionValidationErrorMessage != null) {
+ result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+ "parentKeyVersion invalid-" + parentKeyVersionValidationErrorMessage));
+ }
+
+ final var parentLocalNameValidationErrorMessage = Assertions
+ .getStringParameterValidationMessage(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
+ if (parentLocalNameValidationErrorMessage != null) {
+ result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+ "parentLocalName invalid-" + parentLocalNameValidationErrorMessage));
+ }
+
+ final var localNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(LOCAL_NAME,
+ localName, LOCAL_NAME_REGEXP);
+ if (localNameValidationErrorMessage != null) {
+ result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+ "localName invalid-" + localNameValidationErrorMessage));
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
+ parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
+ parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
+ localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final var builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("parentKeyName=");
+ builder.append(parentKeyName);
+ builder.append(",parentKeyVersion=");
+ builder.append(parentKeyVersion);
+ builder.append(",parentLocalName=");
+ builder.append(parentLocalName);
+ builder.append(",localName=");
+ builder.append(localName);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxReferenceKey.class);
+
+ final AxReferenceKey copy = ((AxReferenceKey) copyObject);
+ copy.setParentKeyName(parentKeyName);
+ copy.setParentKeyVersion(parentKeyVersion);
+ copy.setLocalName(localName);
+ copy.setParentLocalName(parentLocalName);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final var prime = 31;
+ var result = 1;
+ result = prime * result + parentKeyName.hashCode();
+ result = prime * result + parentKeyVersion.hashCode();
+ result = prime * result + parentLocalName.hashCode();
+ result = prime * result + localName.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ throw new IllegalArgumentException("comparison object may not be null");
+ }
+
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxReferenceKey other = (AxReferenceKey) obj;
+
+ if (!parentKeyName.equals(other.parentKeyName)) {
+ return false;
+ }
+ if (!parentKeyVersion.equals(other.parentKeyVersion)) {
+ return false;
+ }
+ if (!parentLocalName.equals(other.parentLocalName)) {
+ return false;
+ }
+ return localName.equals(other.localName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxReferenceKey other = (AxReferenceKey) otherObj;
+ if (!parentKeyName.equals(other.parentKeyName)) {
+ return parentKeyName.compareTo(other.parentKeyName);
+ }
+ if (!parentKeyVersion.equals(other.parentKeyVersion)) {
+ return parentKeyVersion.compareTo(other.parentKeyVersion);
+ }
+ if (!parentLocalName.equals(other.parentLocalName)) {
+ return parentLocalName.compareTo(other.parentLocalName);
+ }
+ return localName.compareTo(other.localName);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxToscaPolicyProcessingStatus.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxToscaPolicyProcessingStatus.java
new file mode 100644
index 000000000..43c7e7866
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxToscaPolicyProcessingStatus.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+/**
+ * This enumeration indicates the status of TOSCA policy processing on an APEX event.
+ */
+public enum AxToscaPolicyProcessingStatus {
+
+ /** Indicates the entrypoint for the processing of a TOSCA Policy. */
+ ENTRY(0),
+
+ /** Indicates a successful exit point for a TOSCA Policy. */
+ EXIT_SUCCESS(1),
+
+ /** Indicates a failure exit point for a TOSCA Policy. */
+ EXIT_FAILURE(2);
+
+ private final int statusCode;
+
+ AxToscaPolicyProcessingStatus(int statusCode) {
+ this.statusCode = statusCode;
+ }
+
+ public int getStatusCode() {
+ return statusCode;
+ }
+} \ No newline at end of file
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxValidationMessage.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxValidationMessage.java
new file mode 100644
index 000000000..9e245c07b
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxValidationMessage.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 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.onap.policy.apex.model.basicmodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * A validation message is created for each validation observation observed during validation of a concept. The message
+ * holds the key and the class of the concept on which the observation was made as well as the type of observation and a
+ * message describing the observation.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class AxValidationMessage {
+ private final AxKey observedKey;
+ private ValidationResult validationResult = ValidationResult.VALID;
+ private final String observedClass;
+ private final String message;
+
+ /**
+ * Create an validation observation with the given fields.
+ *
+ * @param observedKey the key of the class on which the validation observation was made
+ * @param observedClass the class on which the validation observation was made
+ * @param validationResult the type of observation made
+ * @param message a message describing the observation
+ */
+ public AxValidationMessage(final AxKey observedKey, final Class<?> observedClass,
+ final ValidationResult validationResult, final String message) {
+ Assertions.argumentNotNull(observedKey, "observedKey may not be null");
+ Assertions.argumentNotNull(observedClass, "observedClass may not be null");
+ Assertions.argumentNotNull(validationResult, "validationResult may not be null");
+ Assertions.argumentNotNull(message, "message may not be null");
+
+ this.observedKey = observedKey;
+ this.observedClass = observedClass.getName();
+ this.validationResult = validationResult;
+ this.message = message;
+ }
+
+ /**
+ * Gets the key of the observation.
+ *
+ * @return the key of the observation
+ */
+ public AxKey getObservedKey() {
+ return observedKey;
+ }
+
+ /**
+ * Gets the observed class.
+ *
+ * @return the observed class
+ */
+ public String getObservedClass() {
+ return observedClass;
+ }
+
+ /**
+ * Gets the type of observation made.
+ *
+ * @return the type of observation made
+ */
+ public ValidationResult getValidationResult() {
+ return validationResult;
+ }
+
+ /**
+ * Get a description of the observation.
+ *
+ * @return the observation description
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ return observedKey.toString() + ':' + observedClass + ':' + validationResult.name() + ':' + message;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxValidationResult.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxValidationResult.java
new file mode 100644
index 000000000..10ccb30aa
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxValidationResult.java
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This class records the result of a validation and holds all validatino observation messages.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class AxValidationResult {
+ /**
+ * The ValidationResult enumeration describes the severity of a validation result.
+ */
+ public enum ValidationResult {
+ /** No problems or observations were detected during validation. */
+ VALID,
+ /**
+ * Observations were made on a concept (such as blank descriptions) of a nature that will not affect the use of
+ * the concept.
+ */
+ OBSERVATION,
+ /**
+ * Warnings were made on a concept (such as defined but unused concepts) of a nature that may affect the use of
+ * the concept.
+ */
+ WARNING,
+ /**
+ * Errors were detected on a concept (such as referenced but undefined concepts) of a nature that will affect
+ * the use of the concept.
+ */
+ INVALID
+ }
+
+ // The actual verification result
+ private ValidationResult validationResult = ValidationResult.VALID;
+
+ // Messages collected during the verification process
+ private final List<AxValidationMessage> messageList = new LinkedList<>();
+
+ /**
+ * Check if a validation reported a valid concept, returns true if the model is usable (that is, even if the model
+ * has warnings or observations).
+ *
+ * @return true, if the concept is reported as valid and can be used
+ */
+ public boolean isValid() {
+ return validationResult != ValidationResult.INVALID;
+ }
+
+ /**
+ * Check if a validation reported a concept with no errors or warnings, returns true if the model is OK to use.
+ *
+ * @return true, if the concept has no warnings or errors
+ */
+ public boolean isOk() {
+ return validationResult == ValidationResult.VALID || validationResult == ValidationResult.OBSERVATION;
+ }
+
+ /**
+ * Gets the validation result.
+ *
+ * @return the validation result on a concept
+ */
+ public ValidationResult getValidationResult() {
+ return validationResult;
+ }
+
+ /**
+ * Gets the list of validation results on the concept.
+ *
+ * @return the list of validaiton results
+ */
+ public List<AxValidationMessage> getMessageList() {
+ return messageList;
+ }
+
+ /**
+ * Adds a validation message to the validation result, used by validate() implementations on {@link AxConcept}
+ * subclasses to report validaiton observations.
+ *
+ * @param validationMessage the validation message
+ */
+ public void addValidationMessage(final AxValidationMessage validationMessage) {
+ messageList.add(validationMessage);
+
+ // Check if the incoming message has a more sever status than the
+ // current one on the overall validation result,
+ // if so, the overall result goes to that level
+ if (validationMessage.getValidationResult().ordinal() > validationResult.ordinal()) {
+ validationResult = validationMessage.getValidationResult();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+
+ switch (validationResult) {
+ case VALID:
+
+ builder.append("***validation of model successful***");
+ return builder.toString();
+ case OBSERVATION:
+
+ builder.append("\n***observations noted during validation of model***\n");
+ break;
+ case WARNING:
+
+ builder.append("\n***warnings issued during validation of model***\n");
+ break;
+ case INVALID:
+ builder.append("\n***validation of model failed***\n");
+ break;
+ default:
+ break;
+ }
+
+ for (final AxValidationMessage message : messageList) {
+ builder.append(message);
+ builder.append("\n");
+ }
+
+ builder.append("********************************");
+ return builder.toString();
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/package-info.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/package-info.java
new file mode 100644
index 000000000..347e46a0f
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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=========================================================
+ */
+
+/**
+ * This package contains the fundamental concepts for all APEX models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.basicmodel.concepts;
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCreator.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCreator.java
new file mode 100644
index 000000000..a33e1bf1a
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCreator.java
@@ -0,0 +1,41 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+
+/**
+ * This interface is implemented by factories that create Apex models. It is mainly used by unit test classes that
+ * generate Apex models for test purposes.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <M> the type of Apex model to create, must be a sub class of {@link AxModel}
+ */
+@FunctionalInterface
+public interface ApexModelCreator<M extends AxModel> {
+
+ /**
+ * Gets the model created by the model creator.
+ *
+ * @return the model created by the model creator
+ */
+ M getModel();
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCustomGsonMapAdapter.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCustomGsonMapAdapter.java
new file mode 100644
index 000000000..cb67590f7
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCustomGsonMapAdapter.java
@@ -0,0 +1,118 @@
+/*-
+ * ============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.onap.policy.apex.model.basicmodel.handling;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.AbstractMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+@SuppressWarnings("rawtypes")
+public class ApexModelCustomGsonMapAdapter implements JsonSerializer<Map>, JsonDeserializer<Map> {
+ private static final String MAP_ENTRY_KEY = "entry";
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map deserialize(JsonElement jsonElement, Type typeOfT, JsonDeserializationContext context)
+ throws JsonParseException {
+
+ if (!(jsonElement instanceof JsonObject)) {
+ throw new JsonParseException("could not parse JSON map, map is not a JsonObject");
+ }
+
+ JsonObject jsonObject = (JsonObject) jsonElement;
+
+ if (jsonObject.size() != 1) {
+ throw new JsonParseException("could not parse JSON map, map must be in a JsonObject with a single member");
+ }
+
+ JsonArray mapEntryArray = (JsonArray) jsonObject.get(MAP_ENTRY_KEY);
+ if (mapEntryArray == null) {
+ throw new JsonParseException("could not parse JSON map, map \"entry\" in JsonObject not found");
+ }
+
+ return new TreeMap(
+ StreamSupport
+ .stream(mapEntryArray.spliterator(), true)
+ .map(element -> deserializeMapEntry(element, typeOfT, context))
+ .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()))
+ );
+ }
+
+ @Override
+ public JsonElement serialize(Map sourceMap, Type typeOfSrc, JsonSerializationContext context) {
+
+ // A map is stored in a JsonArray
+ JsonArray mapEntryArray = new JsonArray();
+
+ for (Object mapEntryObject : sourceMap.entrySet()) {
+ Entry mapEntry = (Entry) mapEntryObject;
+ mapEntryArray.add(serializeMapEntry(mapEntry, typeOfSrc, context));
+ }
+
+ JsonObject returnObject = new JsonObject();
+ returnObject.add(MAP_ENTRY_KEY, mapEntryArray);
+
+ return returnObject;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Entry deserializeMapEntry(JsonElement element, Type typeOfT, JsonDeserializationContext context) {
+ // Get the types of the map
+ ParameterizedType pt = (ParameterizedType) typeOfT;
+
+ // Type of the key and value of the map
+ Type keyType = pt.getActualTypeArguments()[0];
+ Type valueType = pt.getActualTypeArguments()[1];
+
+ // Deserialize the key and value
+ return new AbstractMap.SimpleEntry(
+ context.deserialize(element.getAsJsonObject().get("key"), keyType),
+ context.deserialize(element.getAsJsonObject().get("value"), valueType));
+ }
+
+ private static JsonElement serializeMapEntry(Entry sourceEntry, Type typeOfSrc, JsonSerializationContext context) {
+ // Get the types of the map
+ ParameterizedType pt = (ParameterizedType) typeOfSrc;
+
+ // Type of the key and value of the map
+ Type keyType = pt.getActualTypeArguments()[0];
+ Type valueType = pt.getActualTypeArguments()[1];
+
+ JsonObject entryObject = new JsonObject();
+ entryObject.add("key", context.serialize(sourceEntry.getKey(), keyType));
+ entryObject.add("value", context.serialize(sourceEntry.getValue(), valueType));
+
+ return entryObject;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCustomGsonRefereceKeyAdapter.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCustomGsonRefereceKeyAdapter.java
new file mode 100644
index 000000000..d731c8689
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelCustomGsonRefereceKeyAdapter.java
@@ -0,0 +1,50 @@
+/*-
+ * ============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.onap.policy.apex.model.basicmodel.handling;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import java.lang.reflect.Type;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+public class ApexModelCustomGsonRefereceKeyAdapter implements JsonDeserializer<AxReferenceKey> {
+
+ @Override
+ public AxReferenceKey deserialize(JsonElement jsonElement, Type typeOfT, JsonDeserializationContext context)
+ throws JsonParseException {
+
+ if (jsonElement instanceof JsonObject) {
+ return new AxReferenceKey(
+ jsonElement.getAsJsonObject().get("parentKeyName").getAsString(),
+ jsonElement.getAsJsonObject().get("parentKeyVersion").getAsString(),
+ jsonElement.getAsJsonObject().get("parentLocalName").getAsString(),
+ jsonElement.getAsJsonObject().get("localName").getAsString()
+ );
+ } else {
+ AxReferenceKey returnKey = new AxReferenceKey();
+ returnKey.setLocalName(jsonElement.getAsString());
+ return returnKey;
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelException.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelException.java
new file mode 100644
index 000000000..17eb2639d
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelException.java
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+
+/**
+ * This exception is invoked if an exception occurs in model handling.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexModelException extends ApexException {
+ private static final long serialVersionUID = -4245694568321686450L;
+
+ /**
+ * Instantiates a new apex model handling exception.
+ *
+ * @param message the message
+ */
+ public ApexModelException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new apex model handling exception.
+ *
+ * @param message the message
+ * @param exception the exception
+ */
+ public ApexModelException(final String message, final Exception exception) {
+ super(message, exception);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelFileWriter.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelFileWriter.java
new file mode 100644
index 000000000..54b5651cc
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelFileWriter.java
@@ -0,0 +1,99 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021-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.onap.policy.apex.model.basicmodel.handling;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import lombok.Getter;
+import lombok.Setter;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class writes an Apex model to a file.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <M> the type of Apex model to write to file, must be a sub class of {@link AxModel}
+ */
+@Getter
+@Setter
+public class ApexModelFileWriter<M extends AxModel> {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexModelFileWriter.class);
+
+ // Should models being written to files be valid
+ private boolean validate;
+
+ /**
+ * Constructor, set the validation flag.
+ *
+ * @param validate indicates if validation be performed prior to output
+ */
+ public ApexModelFileWriter(final boolean validate) {
+ this.validate = validate;
+ }
+
+ /**
+ * Write a model to an JSON file.
+ *
+ * @param model The model to write
+ * @param rootModelClass The concept class
+ * @param modelFileName The name of the file to write to
+ * @throws ApexException thrown on errors
+ */
+ public void apexModelWriteJsonFile(final M model, final Class<M> rootModelClass, final String modelFileName)
+ throws ApexException {
+ LOGGER.debug("running apexModelWriteJSONFile . . .");
+
+ final ApexModelWriter<M> modelWriter = new ApexModelWriter<>(rootModelClass);
+ modelWriter.setValidate(validate);
+
+ writeModelFile(model, modelWriter, modelFileName);
+
+ LOGGER.debug("ran apexModelWriteJSONFile");
+ }
+
+ /**
+ * Write a model to a file using a model writer.
+ *
+ * @param model The model to write
+ * @param modelWriter the model writer to use to write the model to the file
+ * @param modelFileName the file name of the file to write to
+ * @throws ApexException on exceptions writing the model
+ */
+ private void writeModelFile(final M model, final ApexModelWriter<M> modelWriter, final String modelFileName)
+ throws ApexException {
+ final var modelFile = new File(modelFileName);
+ if (!modelFile.getParentFile().exists() && !modelFile.getParentFile().mkdirs()) {
+ LOGGER.warn("could not create directory " + modelFile.getParentFile());
+ throw new ApexException("could not create directory " + modelFile.getParentFile());
+ }
+
+ try (final var fileOutputStream = new FileOutputStream(modelFile)) {
+ modelWriter.write(model, fileOutputStream);
+ } catch (final Exception e) {
+ LOGGER.warn("error processing file " + modelFile.getAbsolutePath(), e);
+ throw new ApexException("error processing file " + modelFile.getAbsolutePath(), e);
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReader.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReader.java
new file mode 100644
index 000000000..a9bd2fe60
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReader.java
@@ -0,0 +1,169 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+import org.onap.policy.common.utils.validation.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class reads an Apex concept from a file into a Java Apex Concept {@link AxConcept}.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <C> the type of Apex concept to read, must be a sub class of {@link AxConcept}
+ */
+@Getter
+@Setter
+public class ApexModelReader<C extends AxConcept> {
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexModelReader.class);
+
+ // Use GSON to deserialize JSON
+ private static Gson gson = new GsonBuilder()
+ .registerTypeAdapter(AxReferenceKey.class, new ApexModelCustomGsonRefereceKeyAdapter())
+ .registerTypeAdapter(Map.class, new ApexModelCustomGsonMapAdapter())
+ .setPrettyPrinting()
+ .create();
+
+ //  The root class of the concept we are reading
+ private final Class<C> rootConceptClass;
+
+ // All read concepts are validated after reading if this flag is set
+ private boolean validate = true;
+
+ /**
+ * Constructor, initiates the reader with validation on.
+ *
+ * @param rootConceptClass the root concept class for concept reading
+ * @throws ApexModelException the apex concept reader exception
+ */
+ public ApexModelReader(final Class<C> rootConceptClass) throws ApexModelException {
+ // Save the root concept class
+ this.rootConceptClass = rootConceptClass;
+ }
+
+ /**
+ * Constructor, initiates the reader.
+ *
+ * @param rootConceptClass the root concept class for concept reading
+ * @param validate whether to perform validation by default
+ * @throws ApexModelException the apex concept reader exception
+ */
+ public ApexModelReader(final Class<C> rootConceptClass, final boolean validate) throws ApexModelException {
+ this(rootConceptClass);
+ this.validate = validate;
+ }
+
+ /**
+ * This method checks the specified Apex concept file and reads it into an Apex concept.
+ *
+ * @param apexConceptStream the apex concept stream
+ * @return the Apex concept
+ * @throws ApexModelException on reading exceptions
+ */
+ public C read(final InputStream apexConceptStream) throws ApexModelException {
+ Assertions.argumentNotNull(apexConceptStream, "concept stream may not be null");
+
+ return read(new BufferedReader(new InputStreamReader(apexConceptStream)));
+ }
+
+ /**
+ * This method reads the specified Apex reader into an Apex concept.
+ *
+ * @param apexConceptReader the apex concept reader
+ * @return the Apex concept
+ * @throws ApexModelException on reading exceptions
+ */
+ public C read(final BufferedReader apexConceptReader) throws ApexModelException {
+ Assertions.argumentNotNull(apexConceptReader, "concept reader may not be null");
+
+ LOGGER.entry("reading Apex concept into a String . . .");
+
+ // Get the Apex concept as a string
+ String apexConceptString = null;
+ try {
+ apexConceptString = TextFileUtils.getReaderAsString(apexConceptReader).trim();
+ } catch (final IOException e) {
+ throw new ApexModelException("Unable to read Apex concept ", e);
+ }
+
+ return read(apexConceptString);
+ }
+
+ /**
+ * This method reads the specified Apex string into an Apex concept.
+ *
+ * @param apexConceptString the apex concept as a string
+ * @return the Apex concept
+ * @throws ApexModelException on reading exceptions
+ */
+ public C read(final String apexConceptString) throws ApexModelException {
+ Assertions.argumentNotNull(apexConceptString, "concept string may not be null");
+
+ LOGGER.entry("reading Apex concept from string . . .");
+
+ C apexConcept = null;
+ try {
+ apexConcept = gson.fromJson(apexConceptString, rootConceptClass);
+ } catch (final Exception je) {
+ throw new ApexModelException("Unable to unmarshal Apex concept ", je);
+ }
+
+ if (apexConcept == null) {
+ throw new ApexModelException("Unable to unmarshal Apex concept, unmarshaled model is null ");
+ }
+
+ LOGGER.debug("reading of Apex concept {} completed");
+
+ apexConcept.buildReferences();
+
+ // Check if the concept should be validated
+ if (validate) {
+ // Validate the configuration file
+ final AxValidationResult validationResult = apexConcept.validate(new AxValidationResult());
+ if (validationResult.isValid()) {
+ return apexConcept;
+ } else {
+ String message = "Apex concept validation failed" + validationResult.toString();
+ LOGGER.error(message);
+ throw new ApexModelException(message);
+ }
+ } else {
+ // No validation check
+ return apexConcept;
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelSaver.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelSaver.java
new file mode 100644
index 000000000..79d69bdd5
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelSaver.java
@@ -0,0 +1,80 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-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.onap.policy.apex.model.basicmodel.handling;
+
+import java.io.File;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.common.utils.validation.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class is used to save Apex models to file in JSON format.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <M> the type of Apex model to save to file, must be a sub class of {@link AxModel}
+ */
+public class ApexModelSaver<M extends AxModel> {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexModelSaver.class);
+
+ // The class of the model and the model to write to disk
+ private final Class<M> rootModelClass;
+ private final M model;
+
+ // The path into which to write the models
+ private final String writePath;
+
+ /**
+ * Constructor, specifies the type of the Apex model (a sub class of {@link AxModel}), the model to write, and the
+ * path of a directory to which to write the model.
+ *
+ * @param rootModelClass the class of the model, a sub class of {@link AxModel}
+ * @param model the model to write, an instance of a sub class of {@link AxModel}
+ * @param writePath the directory to which models will be written. The name of the written model will be the Model
+ * Name for its key with the suffix {@code .json}.
+ */
+ public ApexModelSaver(final Class<M> rootModelClass, final M model, final String writePath) {
+ Assertions.argumentNotNull(rootModelClass, "argument rootModelClass may not be null");
+ Assertions.argumentNotNull(model, "argument model may not be null");
+ Assertions.argumentNotNull(writePath, "writePath rootModelClass may not be null");
+
+ this.rootModelClass = rootModelClass;
+ this.model = model;
+ this.writePath = writePath;
+ }
+
+ /**
+ * Write an Apex model to a file in JSON format. The model will be written to {@code <writePath/modelKeyName.json>}
+ *
+ * @throws ApexException on errors writing the Apex model
+ */
+ public void apexModelWriteJson() throws ApexException {
+ LOGGER.debug("running apexModelWriteJSON . . .");
+
+ // Write the file to disk
+ final var jsonFile = new File(writePath + File.separatorChar + model.getKey().getName() + ".json");
+ new ApexModelFileWriter<M>(true).apexModelWriteJsonFile(model, rootModelClass, jsonFile.getPath());
+
+ LOGGER.debug("ran apexModelWriteJSON");
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelStringWriter.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelStringWriter.java
new file mode 100644
index 000000000..a9df23afc
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelStringWriter.java
@@ -0,0 +1,94 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-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.onap.policy.apex.model.basicmodel.handling;
+
+import java.io.ByteArrayOutputStream;
+import lombok.Getter;
+import lombok.Setter;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.common.utils.validation.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class writes an Apex concept to a string.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <C> the type of Apex concept to write to a string, must be a sub class of {@link AxConcept}
+ */
+@Getter
+@Setter
+public class ApexModelStringWriter<C extends AxConcept> {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexModelStringWriter.class);
+
+ // Should concepts being written to files be valid
+ private boolean validate;
+
+ /**
+ * Constructor, set the validation flag.
+ *
+ * @param validate Should validation be performed prior to output
+ */
+ public ApexModelStringWriter(final boolean validate) {
+ this.validate = validate;
+ }
+
+ /**
+ * Write a concept to a string.
+ *
+ * @param concept The concept to write
+ * @param rootConceptClass The concept class
+ * @return The string with the concept
+ * @throws ApexException thrown on errors
+ */
+ public String writeString(final C concept, final Class<C> rootConceptClass)
+ throws ApexException {
+ Assertions.argumentNotNull(concept, "concept may not be null");
+
+ return writeJsonString(concept, rootConceptClass);
+ }
+
+ /**
+ * Write a concept to a JSON string.
+ *
+ * @param concept The concept to write
+ * @param rootConceptClass The concept class
+ * @return The string with the concept
+ * @throws ApexException thrown on errors
+ */
+ public String writeJsonString(final C concept, final Class<C> rootConceptClass) throws ApexException {
+ LOGGER.debug("running writeJSONString . . .");
+
+ final ApexModelWriter<C> conceptWriter = new ApexModelWriter<>(rootConceptClass);
+ conceptWriter.setValidate(validate);
+
+ try (var baOutputStream = new ByteArrayOutputStream()) {
+ conceptWriter.write(concept, baOutputStream);
+ return baOutputStream.toString();
+ } catch (final Exception e) {
+ LOGGER.warn("error writing JSON string", e);
+ throw new ApexException("error writing JSON string", e);
+ }
+
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriter.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriter.java
new file mode 100644
index 000000000..349622697
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriter.java
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-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.onap.policy.apex.model.basicmodel.handling;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class writes an Apex concept to a file from a Java Apex Concept.
+ *
+ * @param <C> the type of Apex concept to write, must be a sub class of {@link AxConcept}
+ * @author John Keeney (john.keeney@ericsson.com)
+ */
+@Getter
+@Setter
+public class ApexModelWriter<C extends AxConcept> {
+
+ private static final String CONCEPT_MAY_NOT_BE_NULL = "concept may not be null";
+ private static final String CONCEPT_WRITER_MAY_NOT_BE_NULL = "concept writer may not be null";
+ private static final String CONCEPT_STREAM_MAY_NOT_BE_NULL = "concept stream may not be null";
+
+ // Use GSON to serialize JSON
+ private static Gson gson = new GsonBuilder()
+ .registerTypeAdapter(AxReferenceKey.class, new ApexModelCustomGsonRefereceKeyAdapter())
+ .registerTypeAdapter(Map.class, new ApexModelCustomGsonMapAdapter())
+ .setPrettyPrinting()
+ .create();
+
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexModelWriter.class);
+
+ //  The root class of the concept we are reading
+ private final Class<C> rootConceptClass;
+
+ // All written concepts are validated before writing if this flag is set
+ private boolean validate = true;
+
+ /**
+ * Constructor, initiates the writer with validation on.
+ *
+ * @param rootConceptClass the root concept class for concept reading
+ * @throws ApexModelException the apex concept reader exception
+ */
+ public ApexModelWriter(final Class<C> rootConceptClass) throws ApexModelException {
+ // Save the root concept class
+ this.rootConceptClass = rootConceptClass;
+ }
+
+ /**
+ * This method validates the Apex concept then writes it into a stream.
+ *
+ * @param concept the concept to write
+ * @param apexConceptStream the stream to write to
+ * @throws ApexModelException on validation or writing exceptions
+ */
+ public void write(final C concept, final OutputStream apexConceptStream) throws ApexModelException {
+ Assertions.argumentNotNull(concept, CONCEPT_MAY_NOT_BE_NULL);
+ Assertions.argumentNotNull(apexConceptStream, CONCEPT_STREAM_MAY_NOT_BE_NULL);
+
+ this.write(concept, new OutputStreamWriter(apexConceptStream));
+ }
+
+ /**
+ * This method validates the Apex concept then writes it into a writer.
+ *
+ * @param concept the concept to write
+ * @param apexConceptWriter the writer to write to
+ * @throws ApexModelException on validation or writing exceptions
+ */
+ public void write(final C concept, final Writer apexConceptWriter) throws ApexModelException {
+ Assertions.argumentNotNull(concept, CONCEPT_MAY_NOT_BE_NULL);
+ Assertions.argumentNotNull(apexConceptWriter, CONCEPT_WRITER_MAY_NOT_BE_NULL);
+
+ // Check if we should validate the concept
+ if (validate) {
+ // Validate the concept first
+ final AxValidationResult validationResult = concept.validate(new AxValidationResult());
+ if (!validationResult.isValid()) {
+ String message =
+ "Apex concept (" + concept.getKey().getId() + ") validation failed: " + validationResult.toString();
+ throw new ApexModelException(message);
+ }
+ }
+
+ writeJson(concept, apexConceptWriter);
+ }
+
+ /**
+ * This method writes the Apex concept into a writer in JSON format.
+ *
+ * @param concept the concept to write
+ * @param apexConceptWriter the writer to write to
+ * @throws ApexModelException on validation or writing exceptions
+ */
+ private void writeJson(final C concept, final Writer apexConceptWriter) throws ApexModelException {
+ Assertions.argumentNotNull(concept, CONCEPT_MAY_NOT_BE_NULL);
+
+ LOGGER.debug("writing Apex concept JSON . . .");
+
+ String modelJsonString = null;
+ try {
+ modelJsonString = gson.toJson(concept, rootConceptClass);
+ } catch (Exception je) {
+ throw new ApexModelException("Unable to marshal Apex concept to JSON", je);
+ }
+
+ try {
+ apexConceptWriter.write(modelJsonString);
+ apexConceptWriter.close();
+ } catch (IOException ioe) {
+ throw new ApexModelException("Unable to write Apex concept as JSON", ioe);
+ }
+
+ LOGGER.debug("wrote Apex concept JSON");
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/package-info.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/package-info.java
new file mode 100644
index 000000000..3d6dab3b2
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/package-info.java
@@ -0,0 +1,21 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.basicmodel.handling;
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/package-info.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/package-info.java
new file mode 100644
index 000000000..8ad405e25
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,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=========================================================
+ */
+
+/**
+ * Provides the base definition of an APEX model. It also defines the Model Service, the mechanism that allows access to
+ * the model for APEX concepts anywhere in the system.
+ *
+ * <p>It also provides handling support to models, allowing them to be read and written to file and databases in JSON
+ * format.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.basicmodel;
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/service/ModelService.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/service/ModelService.java
new file mode 100644
index 000000000..c6eb0e011
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/service/ModelService.java
@@ -0,0 +1,108 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 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.onap.policy.apex.model.basicmodel.service;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+
+/**
+ * The model service makes Apex models available to all classes in a JVM.
+ *
+ * <p>The reason for having a model service is to avoid having to pass concept and model definitions down long call
+ * chains in modules such as the Apex engine and editor. The model service makes the model and concept definitions
+ * available statically.
+ *
+ * <p>Note that the use of the model service means that only a single Apex model of a particular type may exist in Apex
+ * (particularly the engine) at any time. Of course the model in a JVM can be changed at any time provided all users of
+ * the model are stopped and restarted in an orderly manner.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public abstract class ModelService {
+ // The map holding the models
+ private static Map<Class<?>, AxConcept> modelMap = new ConcurrentHashMap<>();
+
+ /**
+ * This class is an abstract static class that cannot be extended.
+ */
+ private ModelService() {
+ }
+
+ /**
+ * Register a model with the model service.
+ *
+ * @param <M> the generic type
+ * @param modelClass the class of the model, used to index the model
+ * @param model The model
+ */
+ public static <M extends AxConcept> void registerModel(final Class<M> modelClass, final M model) {
+ modelMap.put(modelClass, model);
+ }
+
+ /**
+ * Remove a model from the model service.
+ *
+ * @param <M> the generic type
+ * @param modelClass the class of the model, used to index the model
+ */
+ public static <M extends AxConcept> void deregisterModel(final Class<M> modelClass) {
+ modelMap.remove(modelClass);
+ }
+
+ /**
+ * Get a model from the model service.
+ *
+ * @param <M> the generic type
+ * @param modelClass the class of the model, used to index the model
+ * @return The model
+ */
+ @SuppressWarnings("unchecked")
+ public static <M extends AxConcept> M getModel(final Class<M> modelClass) {
+ final M model = (M) modelMap.get(modelClass);
+
+ if (model == null) {
+ throw new ApexRuntimeException("Model for " + modelClass.getName() + " not found in model service");
+ }
+
+ return model;
+ }
+
+ /**
+ * Check if a model is defined on the model service.
+ *
+ * @param <M> the generic type
+ * @param modelClass the class of the model, used to index the model
+ * @return true if the model is defined
+ */
+ public static <M extends AxConcept> boolean existsModel(final Class<M> modelClass) {
+ return modelMap.get(modelClass) != null;
+ }
+
+ /**
+ * Clear all models in the model service.
+ */
+ public static void clear() {
+ modelMap.clear();
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/service/package-info.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/service/package-info.java
new file mode 100644
index 000000000..a27e45d1a
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/service/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Contains the static services in Apex that make models and parameters available to all objects in the JVM.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.basicmodel.service;
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/TestApexModel.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/TestApexModel.java
new file mode 100644
index 000000000..9dde47d05
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/TestApexModel.java
@@ -0,0 +1,259 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021-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.onap.policy.apex.model.basicmodel.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelFileWriter;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelWriter;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class tests reading and writing of Apex models to file and to a database using JPA. It also tests validation of
+ * Apex models. This class is designed for use in unit tests in modules that define Apex models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <M> the generic type
+ */
+public class TestApexModel<M extends AxModel> {
+ private static final String MODEL_IS_INVALID = "model is invalid ";
+ private static final String ERROR_PROCESSING_FILE = "error processing file ";
+ private static final String TEST_MODEL_UNEQUAL_STR = "test model does not equal model read from file ";
+ private static final String TEMP_FILE_CREATE_ERR_STR = "error creating temporary file for Apex model";
+
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(TestApexModel.class);
+
+ // The root model class that specifies the root to import and export from
+ private final Class<M> rootModelClass;
+
+ // The class that provides the model
+ private TestApexModelCreator<M> modelCreator = null;
+
+ /**
+ * Constructor, defines the subclass of {@link AxModel} that is being tested and the {@link TestApexModelCreator}
+ * object that is used to generate Apex models.
+ *
+ * @param rootModelClass the Apex model class, a sub class of {@link AxModel}
+ * @param modelCreator the @link TestApexModelCreator} that will generate Apex models of various types for testing
+ */
+ public TestApexModel(final Class<M> rootModelClass, final TestApexModelCreator<M> modelCreator) {
+ this.rootModelClass = rootModelClass;
+ this.modelCreator = modelCreator;
+ }
+
+ /**
+ * Get a test Apex model using the model creator.
+ *
+ * @return the test Apex model
+ */
+ public final M getModel() {
+ return modelCreator.getModel();
+ }
+
+ /**
+ * Test write and read in JSON format.
+ *
+ * @throws ApexException on write/read errors
+ */
+ public final void testApexModelWriteReadJson() throws ApexException {
+ LOGGER.debug("running testApexModelWriteReadJSON . . .");
+
+ final var model = modelCreator.getModel();
+
+ // Write the file to disk
+ File jsonFile;
+ try {
+ jsonFile = File.createTempFile("ApexModel", ".json");
+ jsonFile.deleteOnExit();
+ } catch (final Exception e) {
+ LOGGER.warn(TEMP_FILE_CREATE_ERR_STR, e);
+ throw new ApexException(TEMP_FILE_CREATE_ERR_STR, e);
+ }
+ new ApexModelFileWriter<M>(true).apexModelWriteJsonFile(model, rootModelClass, jsonFile.getPath());
+
+ // Read the file from disk
+ final ApexModelReader<M> modelReader = new ApexModelReader<>(rootModelClass);
+
+ try {
+ final var apexModelUrl = ResourceUtils.getLocalFile(jsonFile.getAbsolutePath());
+ final var fileModel = modelReader.read(apexModelUrl.openStream());
+ checkModelEquality(model, fileModel, TEST_MODEL_UNEQUAL_STR + jsonFile.getAbsolutePath());
+ } catch (final Exception e) {
+ LOGGER.warn(ERROR_PROCESSING_FILE + jsonFile.getAbsolutePath(), e);
+ throw new ApexException(ERROR_PROCESSING_FILE + jsonFile.getAbsolutePath(), e);
+ }
+
+ final ApexModelWriter<M> modelWriter = new ApexModelWriter<>(rootModelClass);
+
+ final var baOutputStream = new ByteArrayOutputStream();
+ modelWriter.write(model, baOutputStream);
+ final var baInputStream = new ByteArrayInputStream(baOutputStream.toByteArray());
+ final var byteArrayModel = modelReader.read(baInputStream);
+
+ checkModelEquality(model, byteArrayModel, "test model does not equal JSON marshalled and unmarshalled model");
+
+ LOGGER.debug("ran testApexModelWriteReadJSON");
+ }
+
+ /**
+ * Test that an Apex model is valid.
+ *
+ * @return the result of the validation
+ * @throws ApexException thrown on errors validating the Apex model
+ */
+ public final AxValidationResult testApexModelValid() throws ApexException {
+ LOGGER.debug("running testApexModelVaid . . .");
+
+ final var model = modelCreator.getModel();
+ final AxValidationResult result = model.validate(new AxValidationResult());
+
+ if (!result.isValid()) {
+ String message = MODEL_IS_INVALID + result.toString();
+ LOGGER.warn(message);
+ throw new ApexException(message);
+ }
+
+ LOGGER.debug("ran testApexModelVaid");
+ return result;
+ }
+
+ /**
+ * Test that an Apex model is structured incorrectly.
+ *
+ * @return the result of the validation
+ * @throws ApexException thrown on errors validating the Apex model
+ */
+ public final AxValidationResult testApexModelVaidateMalstructured() throws ApexException {
+ LOGGER.debug("running testApexModelVaidateMalstructured . . .");
+
+ final var model = modelCreator.getMalstructuredModel();
+ final AxValidationResult result = model.validate(new AxValidationResult());
+
+ if (result.isValid()) {
+ String message = "model should not be valid " + result.toString();
+ LOGGER.warn(message);
+ throw new ApexException(message);
+ }
+
+ LOGGER.debug("ran testApexModelVaidateMalstructured");
+ return result;
+ }
+
+ /**
+ * Test that an Apex model has observations.
+ *
+ * @return the result of the validation
+ * @throws ApexException thrown on errors validating the Apex model
+ */
+ public final AxValidationResult testApexModelVaidateObservation() throws ApexException {
+ LOGGER.debug("running testApexModelVaidateObservation . . .");
+
+ final var model = modelCreator.getObservationModel();
+ final AxValidationResult result = model.validate(new AxValidationResult());
+
+ if (!result.isValid()) {
+ String message = MODEL_IS_INVALID + result.toString();
+ LOGGER.warn(message);
+ throw new ApexException(message);
+ }
+
+ if (!result.getValidationResult().equals(AxValidationResult.ValidationResult.OBSERVATION)) {
+ LOGGER.warn("model should have observations");
+ throw new ApexException("model should have observations");
+ }
+
+ LOGGER.debug("ran testApexModelVaidateObservation");
+ return result;
+ }
+
+ /**
+ * Test that an Apex model has warnings.
+ *
+ * @return the result of the validation
+ * @throws ApexException thrown on errors validating the Apex model
+ */
+ public final AxValidationResult testApexModelVaidateWarning() throws ApexException {
+ LOGGER.debug("running testApexModelVaidateWarning . . .");
+
+ final var model = modelCreator.getWarningModel();
+ final AxValidationResult result = model.validate(new AxValidationResult());
+
+ if (!result.isValid()) {
+ String message = MODEL_IS_INVALID + result.toString();
+ LOGGER.warn(message);
+ throw new ApexException(message);
+ }
+
+ if (!result.getValidationResult().equals(AxValidationResult.ValidationResult.WARNING)) {
+ LOGGER.warn("model should have warnings");
+ throw new ApexException("model should have warnings");
+ }
+
+ LOGGER.debug("ran testApexModelVaidateWarning");
+ return result;
+ }
+
+ /**
+ * Test that an Apex model is invalid.
+ *
+ * @return the result of the validation
+ * @throws ApexException thrown on errors validating the Apex model
+ */
+ public final AxValidationResult testApexModelVaidateInvalidModel() throws ApexException {
+ LOGGER.debug("running testApexModelVaidateInvalidModel . . .");
+
+ final var model = modelCreator.getInvalidModel();
+ final AxValidationResult result = model.validate(new AxValidationResult());
+
+ if (result.isValid()) {
+ String message = "model should not be valid " + result.toString();
+ LOGGER.warn(message);
+ throw new ApexException(message);
+ }
+
+ LOGGER.debug("ran testApexModelVaidateInvalidModel");
+ return result;
+ }
+
+ /**
+ * Check if two models are equal.
+ *
+ * @param leftModel the left model
+ * @param rightModel the right model
+ * @param errorMessage the error message to output on inequality
+ * @throws ApexException the exception to throw on inequality
+ */
+ public void checkModelEquality(final M leftModel, final M rightModel, final String errorMessage)
+ throws ApexException {
+ if (!leftModel.equals(rightModel)) {
+ LOGGER.warn(errorMessage);
+ throw new ApexException(errorMessage);
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/TestApexModelCreator.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/TestApexModelCreator.java
new file mode 100644
index 000000000..65441a33c
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/TestApexModelCreator.java
@@ -0,0 +1,62 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.test;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelCreator;
+
+/**
+ * The Interface TestApexModelCreator is used to create models for Apex model tests. It is mainly used by unit tests for
+ * Apex domain models so that developers can write test Java programs to create models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <M> the generic type
+ */
+public interface TestApexModelCreator<M extends AxModel> extends ApexModelCreator<M> {
+
+ /**
+ * Gets the malstructured model.
+ *
+ * @return the malstructured model
+ */
+ M getMalstructuredModel();
+
+ /**
+ * Gets the observation model.
+ *
+ * @return the observation model
+ */
+ M getObservationModel();
+
+ /**
+ * Gets the warning model.
+ *
+ * @return the warning model
+ */
+ M getWarningModel();
+
+ /**
+ * Gets the invalid model.
+ *
+ * @return the invalid model
+ */
+ M getInvalidModel();
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/package-info.java b/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/package-info.java
new file mode 100644
index 000000000..9bbdd1cce
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/basicmodel/test/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Contains utility classes that allow testing of validation and reads and writes on APEX models to files and databases.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.basicmodel.test;
diff --git a/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbum.java b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbum.java
new file mode 100644
index 000000000..db64f8847
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbum.java
@@ -0,0 +1,268 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.concepts;
+
+import java.util.List;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is used to define an album of context.
+ *
+ * <p>A context album is a distributed map of context that will be distributed across all process instances that require
+ * access to it. This class defines the schema (structure) of the items in the context album, whether the items on the
+ * context album are writable or not, and what the scope of the context album is.
+ *
+ * <p>The structure of items (objects) the context album is defined as a schema, which is understood by whatever schema
+ * implementation is being used for the context album.
+ *
+ * <p>The scope of a context album is a string field, understood by whatever distribution mechanism is being used for
+ * the context album. The distribution mechanism uses the scope of the context album to decide to which executable
+ * entities a given context album is distributed.
+ *
+ * <p>The writable flag on a context album defines whether users of a context album can write to the context album or
+ * just read objects from the context album.
+ *
+ * <p>Validation checks that the album key and the context schema key are not null and that the scope field is not
+ * undefined and matches the regular expression SCOPE_REGEXP.
+ */
+
+@Getter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+
+public class AxContextAlbum extends AxConcept {
+ private static final String SCOPE_STRING = "scope";
+
+ private static final long serialVersionUID = 4290442590545820316L;
+
+ /**
+ * The legal values for the scope of a context album is constrained by this regular expression.
+ */
+ public static final String SCOPE_REGEXP = "[A-Za-z0-9\\-_]+";
+
+ /** The value of scope for a context album for which a scope has not been specified. */
+ public static final String SCOPE_UNDEFINED = "UNDEFINED";
+
+ private AxArtifactKey key;
+ private String scope;
+
+ @Setter
+ private boolean isWritable;
+
+ private AxArtifactKey itemSchema;
+
+ /**
+ * The default constructor creates a context album with a null artifact key. The scope of the context album is set
+ * as SCOPE_UNDEFINED, the album is writable, and the artifact key of the context schema is set to the null artifact
+ * key.
+ */
+ public AxContextAlbum() {
+ this(new AxArtifactKey());
+ scope = SCOPE_UNDEFINED;
+ isWritable = true;
+ itemSchema = AxArtifactKey.getNullKey();
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextAlbum(final AxContextAlbum copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The keyed constructor creates a context album with the specified artifact key. The scope of the context album is
+ * set as SCOPE_UNDEFINED, the album is writable, and the artifact key of the context schema is set to the null
+ * artifact key.
+ *
+ * @param key the key of the context album
+ */
+ public AxContextAlbum(final AxArtifactKey key) {
+ this(key, SCOPE_UNDEFINED, true, AxArtifactKey.getNullKey());
+ }
+
+ /**
+ * Constructor that sets all the fields of the context album.
+ *
+ * @param key the key of the context album
+ * @param scope the scope field, must match the regular expression SCOPE_REGEXP
+ * @param isWritable specifies whether the context album will be writable or not
+ * @param itemSchema the artifact key of the context schema to use for this context album
+ */
+ public AxContextAlbum(final AxArtifactKey key, final String scope, final boolean isWritable,
+ final AxArtifactKey itemSchema) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(scope, "scope may not be null");
+ Assertions.argumentNotNull(itemSchema, "itemSchema may not be null");
+
+ this.key = key;
+ this.scope = Assertions.validateStringParameter(SCOPE_STRING, scope, SCOPE_REGEXP);
+ this.isWritable = isWritable;
+ this.itemSchema = itemSchema;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.add(new AxKeyUse(itemSchema.getKey()));
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the context album.
+ *
+ * @param key the context album key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Sets the scope of the context album.
+ *
+ * @param scope the context album scope
+ */
+ public void setScope(final String scope) {
+ Assertions.argumentNotNull(scope, "scope may not be null");
+ this.scope = Assertions.validateStringParameter(SCOPE_STRING, scope, SCOPE_REGEXP);
+ }
+
+ /**
+ * Sets the artifact key of the item schema of this context album.
+ *
+ * @param itemSchema the item schema key
+ */
+ public void setItemSchema(final AxArtifactKey itemSchema) {
+ Assertions.argumentNotNull(itemSchema, "itemSchema key may not be null");
+ this.itemSchema = itemSchema;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+ result = key.validate(result);
+
+ if (scope.replaceAll("\\s+$", "").length() == 0 || scope.equals(SCOPE_UNDEFINED)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "scope is not defined"));
+ }
+
+ var stringCheckResult = Assertions.getStringParameterValidationMessage(SCOPE_STRING, scope, SCOPE_REGEXP);
+ if (stringCheckResult != null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "scope invalid-" + stringCheckResult));
+ }
+
+ if (itemSchema.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "itemSchema reference is a null key, an item schema must be specified"));
+ }
+ result = itemSchema.validate(result);
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ scope = Assertions.validateStringParameter(SCOPE_STRING, scope, SCOPE_REGEXP);
+ itemSchema.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "targetObject may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextAlbum.class);
+
+ final AxContextAlbum copy = ((AxContextAlbum) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setScope(scope);
+ copy.setWritable(isWritable);
+ copy.setItemSchema(new AxArtifactKey(itemSchema));
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextAlbum other = (AxContextAlbum) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!scope.equals(other.scope)) {
+ return scope.compareTo(other.scope);
+ }
+ if (isWritable != other.isWritable) {
+ return (isWritable ? 1 : -1);
+ }
+ return itemSchema.compareTo(other.itemSchema);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbums.java b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbums.java
new file mode 100644
index 000000000..54e3ce44b
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbums.java
@@ -0,0 +1,310 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+import lombok.AccessLevel;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is a context album container and holds a map of the context albums for an entire Apex model. All Apex
+ * models that use context albums must have an {@link AxContextAlbums} field. The {@link AxContextAlbums} class
+ * implements the helper methods of the {@link AxConceptGetter} interface to allow {@link AxContextAlbum} instances to
+ * be retrieved by calling methods directly on this class without referencing the contained map.
+ *
+ * <p>Validation checks that the container key is not null. An observation is issued if no context albums are defined in
+ * the container. If context albums do exist, they are checked to ensure that keys and values are not null and that the
+ * map key matches the key in the map value for all album entries. Each context album entry is then validated
+ * individually.
+ */
+@Getter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+public final class AxContextAlbums extends AxConcept implements AxConceptGetter<AxContextAlbum> {
+ private static final long serialVersionUID = -4844259809024470975L;
+
+ private AxArtifactKey key;
+
+ @Getter(AccessLevel.NONE)
+ private Map<AxArtifactKey, AxContextAlbum> albums;
+
+ /**
+ * The Default Constructor creates a {@link AxContextAlbums} object with a null artifact key and creates an empty
+ * context album map.
+ */
+ public AxContextAlbums() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextAlbums(final AxContextAlbums copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxContextAlbums} object with the given artifact key and creates an empty
+ * context album map.
+ *
+ * @param key the key of the context album container
+ */
+ public AxContextAlbums(final AxArtifactKey key) {
+ this(key, new TreeMap<>());
+ }
+
+ /**
+ * Constructor that creates the context album map with the given albums and key.
+ *
+ * @param key the key of the context album container
+ * @param albums the context albums to place in this context album container
+ */
+ public AxContextAlbums(final AxArtifactKey key, final Map<AxArtifactKey, AxContextAlbum> albums) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(albums, "albums may not be null");
+
+ this.key = key;
+ this.albums = new TreeMap<>();
+ this.albums.putAll(albums);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ for (final AxContextAlbum contextAlbum : albums.values()) {
+ keyList.addAll(contextAlbum.getKeys());
+ }
+
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void buildReferences() {
+ albums.values().stream().forEach(album -> album.buildReferences());
+ }
+
+ /**
+ * Sets the key of the context album container.
+ *
+ * @param key the context album container key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the map of context albums from the context album container.
+ *
+ * @return the context album map
+ */
+ public Map<AxArtifactKey, AxContextAlbum> getAlbumsMap() {
+ return albums;
+ }
+
+ /**
+ * Sets the map of context albums from the context album container.
+ *
+ * @param albumsMap the map of context albums to place in the container
+ */
+ public void setAlbumsMap(final Map<AxArtifactKey, AxContextAlbum> albumsMap) {
+ Assertions.argumentNotNull(albumsMap, "albums may not be null");
+ this.albums = new TreeMap<>();
+ this.albums.putAll(albumsMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry : albums.entrySet()) {
+ contextAlbumEntry.getKey().clean();
+ contextAlbumEntry.getValue().clean();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (albums.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "albums are empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry : albums.entrySet()) {
+ if (contextAlbumEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on context album entry " + contextAlbumEntry.getKey()
+ + " may not be the null key"));
+ } else if (contextAlbumEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on context album entry " + contextAlbumEntry.getKey() + " may not be null"));
+ } else {
+ validateContextAlbumKey(result, contextAlbumEntry);
+
+ result = contextAlbumEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void validateContextAlbumKey(final AxValidationResult result,
+ final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry) {
+ if (!contextAlbumEntry.getKey().equals(contextAlbumEntry.getValue().getKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on context album entry key " + contextAlbumEntry.getKey()
+ + " does not equal context album value key "
+ + contextAlbumEntry.getValue().getKey()));
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextAlbums.class);
+
+ final AxContextAlbums copy = ((AxContextAlbums) copyObject);
+ copy.setKey(key);
+ final Map<AxArtifactKey, AxContextAlbum> newContextAlbum = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry : albums.entrySet()) {
+ newContextAlbum.put(new AxArtifactKey(contextAlbumEntry.getKey()),
+ new AxContextAlbum(contextAlbumEntry.getValue()));
+ }
+ copy.setAlbumsMap(newContextAlbum);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextAlbums other = (AxContextAlbums) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!albums.equals(other.albums)) {
+ return (albums.hashCode() - other.albums.hashCode());
+ }
+
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxContextAlbum get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).get(conceptKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxContextAlbum get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).get(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxContextAlbum get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxContextAlbum> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).getAll(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxContextAlbum> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextModel.java b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextModel.java
new file mode 100644
index 000000000..1effe8079
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextModel.java
@@ -0,0 +1,222 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.concepts;
+
+import java.util.List;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * A container class for an Apex context model. This class is a container class that allows an Apex model to be
+ * constructed that just contains context and the key information for that context. The model contains schema
+ * definitions and the definitions of context albums that use those schemas. In the case where Apex context is being
+ * used without policy or independent of policy, an Apex context model is sufficient to get Apex context working.
+ *
+ * <p>Validation runs {@link AxModel} validation on the model. In addition, the {@link AxContextSchemas} and
+ * {@link AxContextAlbums} validation is run on the context schemas and albums in the model.
+ */
+@Getter
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class AxContextModel extends AxModel {
+ private static final long serialVersionUID = 8800599637708309945L;
+
+ private AxContextSchemas schemas;
+ private AxContextAlbums albums;
+
+ /**
+ * The Default Constructor creates a {@link AxContextModel} object with a null artifact key and creates an empty
+ * context model.
+ */
+ public AxContextModel() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxContextModel} object with the given artifact key and creates an empty
+ * context model.
+ *
+ * @param key the key of the context model
+ */
+ public AxContextModel(final AxArtifactKey key) {
+ this(key, new AxContextSchemas(new AxArtifactKey(key.getName() + "_Schemas", key.getVersion())),
+ new AxContextAlbums(new AxArtifactKey(key.getName() + "_Albums", key.getVersion())),
+ new AxKeyInformation(new AxArtifactKey(key.getName() + "_KeyInfo", key.getVersion())));
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextModel(final AxContextModel copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor that initiates a {@link AxContextModel} with schemas and keys for those schemas. An empty
+ * {@link AxContextAlbums} container is created.
+ *
+ * @param key the key of the context model
+ * @param schemas the context schema definitions
+ * @param keyInformation the key information for those context schemas
+ */
+ public AxContextModel(final AxArtifactKey key, final AxContextSchemas schemas,
+ final AxKeyInformation keyInformation) {
+ this(key, schemas, new AxContextAlbums(new AxArtifactKey(key.getName() + "_Albums", key.getVersion())),
+ keyInformation);
+ }
+
+ /**
+ * Constructor that initiates a {@link AxContextModel} with all its fields.
+ *
+ * @param key the key of the context model
+ * @param schemas the context schema definitions
+ * @param albums the context album container containing context albums
+ * @param keyInformation the key information for those context schemas
+ */
+ public AxContextModel(final AxArtifactKey key, final AxContextSchemas schemas, final AxContextAlbums albums,
+ final AxKeyInformation keyInformation) {
+ super(key, keyInformation);
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ Assertions.argumentNotNull(albums, "albums may not be null");
+ this.schemas = schemas;
+ this.albums = albums;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void register() {
+ super.register();
+ ModelService.registerModel(AxContextSchemas.class, getSchemas());
+ ModelService.registerModel(AxContextAlbums.class, getAlbums());
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = super.getKeys();
+
+ keyList.addAll(schemas.getKeys());
+ keyList.addAll(albums.getKeys());
+
+ return keyList;
+ }
+
+ /**
+ * Sets the context schemas on the model.
+ *
+ * @param schemas the context schemas
+ */
+ public void setSchemas(final AxContextSchemas schemas) {
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ this.schemas = schemas;
+ }
+
+ /**
+ * Sets the context albums on the model.
+ *
+ * @param albums the context albums
+ */
+ public void setAlbums(final AxContextAlbums albums) {
+ Assertions.argumentNotNull(albums, "albums may not be null");
+ this.albums = albums;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ result = super.validate(result);
+ result = schemas.validate(result);
+ return albums.validate(result);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ super.clean();
+ schemas.clean();
+ albums.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextModel.class);
+
+ final AxContextModel copy = ((AxContextModel) copyObject);
+ super.copyTo(target);
+ copy.setSchemas(new AxContextSchemas(schemas));
+ copy.setAlbums(new AxContextAlbums(albums));
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextModel other = (AxContextModel) otherObj;
+ if (!super.equals(other)) {
+ return super.compareTo(other);
+ }
+ if (!schemas.equals(other.schemas)) {
+ return schemas.compareTo(other.schemas);
+ }
+ return albums.compareTo(other.albums);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextSchema.java b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextSchema.java
new file mode 100644
index 000000000..61434ca67
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextSchema.java
@@ -0,0 +1,299 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.concepts;
+
+import java.util.List;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.ToString;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class holds a data schema definition in Apex. A data schema describes the structure of a single atom of data
+ * handled by Apex. This atom of data can be a primitive type such as an integer or a string, or it can be a more
+ * complex data type such as a Java object or an object described using a data definition language such as Avro. The
+ * schema flavour defines the type of schema being defined and the schema itself defines the schema. The schema flavour
+ * is used by Apex to look up and load a plugin class that understands and interprets the schema definition and can
+ * create instances of classes for the schema.
+ *
+ * <p>An {@link AxContextSchema} is used to define each parameter in Apex events, the messages that enter, exit, and are
+ * passed internally in Apex. In addition, an Apex {@link AxContextAlbum} instances hold a map of
+ * {@link AxContextSchema} instances to represent the context being managed as an {@link AxContextAlbum}. For example,
+ * the state of all cells in a mobile network might be represented as an {@link AxContextAlbum} with its
+ * {@link AxContextSchema} being defined as @code cell} objects.
+ *
+ * <p>Validation checks that the schema key is not null. It also checks that the schema flavour is defined and matches
+ * the regular expression SCHEMA_FLAVOUR_REGEXP. Finally, validation checks that the defined schema is not a blank or
+ * empty string.
+ */
+@Getter
+@ToString
+public class AxContextSchema extends AxConcept {
+ private static final String SCHEMA_FLAVOUR = "schemaFlavour";
+ private static final String WHITESPACE_REGEXP = "\\s+$";
+
+ private static final long serialVersionUID = -6443016863162692288L;
+
+ /** Regular expression that constrains what values a schema flavour can have. */
+ public static final String SCHEMA_FLAVOUR_REGEXP = "[A-Za-z0-9\\-_]+";
+
+ /** An undefined schema flavour has this value. */
+ public static final String SCHEMA_FLAVOUR_UNDEFINED = "UNDEFINED";
+
+ /** The maximum permissible size of a schema definition. */
+ public static final int MAX_SCHEMA_SIZE = 32672; // The maximum size supported by Apache Derby
+
+ private AxArtifactKey key;
+ private String schemaFlavour;
+
+ @Getter(AccessLevel.NONE)
+ private String schemaDefinition;
+
+ /**
+ * The default constructor creates a context schema with a null artifact key. The flavour of the context album is
+ * set as SCHEMA_FLAVOUR_UNDEFINED and the schema itself is defined as an empty string.
+ */
+ public AxContextSchema() {
+ this(new AxArtifactKey());
+ schemaFlavour = SCHEMA_FLAVOUR_UNDEFINED;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextSchema(final AxContextSchema copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The key constructor creates a context schema with the given artifact key. The flavour of the context album is set
+ * as SCHEMA_FLAVOUR_UNDEFINED and the schema itself is defined as an empty string.
+ *
+ * @param key the key
+ */
+ public AxContextSchema(final AxArtifactKey key) {
+ this(key, SCHEMA_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a context schema with all of its fields defined.
+ *
+ * @param key the key
+ * @param schemaFlavour the schema flavour
+ * @param schemaDefinition the schema definition
+ */
+ public AxContextSchema(final AxArtifactKey key, final String schemaFlavour, final String schemaDefinition) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(schemaFlavour, "schemaFlavour may not be null");
+ Assertions.argumentNotNull(schemaDefinition, "schemaDefinition may not be null");
+
+ this.key = key;
+ this.schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
+ this.schemaDefinition = schemaDefinition.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return key.getKeys();
+ }
+
+ /**
+ * Sets the key of the context schema.
+ *
+ * @param key the key of the context schema
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Sets the schema flavour, which defines the type of schema definition being used.
+ *
+ * @param schemaFlavour the schema flavour
+ */
+ public void setSchemaFlavour(final String schemaFlavour) {
+ this.schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
+ }
+
+ /**
+ * Gets the schema, which defines the structure of this data schema atom.
+ *
+ * @return the schema definition
+ */
+ public String getSchema() {
+ return schemaDefinition;
+ }
+
+ /**
+ * Sets the schema, which defines the structure of this data schema atom.
+ *
+ * @param schema the schema definition
+ */
+ public void setSchema(final String schema) {
+ Assertions.argumentNotNull(schema, "schema may not be null");
+ this.schemaDefinition = schema.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (schemaFlavour.replaceAll(WHITESPACE_REGEXP, "").length() == 0
+ || schemaFlavour.equals(SCHEMA_FLAVOUR_UNDEFINED)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "schema flavour is not defined"));
+ }
+
+ var flavourValidationResult = Assertions.getStringParameterValidationMessage(SCHEMA_FLAVOUR, schemaFlavour,
+ SCHEMA_FLAVOUR_REGEXP);
+ if (flavourValidationResult != null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "schema flavour invalid-" + flavourValidationResult));
+ }
+
+ if (schemaDefinition.replaceAll(WHITESPACE_REGEXP, "").length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "no schemaDefinition specified, schemaDefinition may not be blank"));
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
+ schemaDefinition = schemaDefinition.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextSchema.class);
+
+ final AxContextSchema copy = ((AxContextSchema) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setSchemaFlavour(schemaFlavour);
+ copy.setSchema(schemaDefinition);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final var prime = 31;
+ var result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + schemaFlavour.hashCode();
+
+ final String thisSchema = schemaDefinition.replace("\n", "");
+ result = prime * result + thisSchema.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxContextSchema other = (AxContextSchema) obj;
+
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!schemaFlavour.equals(other.schemaFlavour)) {
+ return false;
+ }
+ return schemaDefinition.equals(other.schemaDefinition);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextSchema other = (AxContextSchema) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!schemaFlavour.equals(other.schemaFlavour)) {
+ return schemaFlavour.compareTo(other.schemaFlavour);
+ }
+ return schemaDefinition.compareTo(other.schemaDefinition);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextSchemas.java b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextSchemas.java
new file mode 100644
index 000000000..5b79a3dcb
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextSchemas.java
@@ -0,0 +1,304 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+import lombok.AccessLevel;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is a context schema container and holds a map of the context schemas for an entire Apex model. All Apex
+ * models that use context schemas must have an {@link AxContextSchemas} field. The {@link AxContextSchemas} class
+ * implements the helper methods of the {@link AxConceptGetter} interface to allow {@link AxContextSchema} instances to
+ * be retrieved by calling methods directly on this class without referencing the contained map.
+ *
+ * <p>Validation checks that the container key is not null. An error is issued if no context schemas are defined in the
+ * container. Each context schema entry is checked to ensure that its key and value are not null and that the key
+ * matches the key in the map value. Each context schema entry is then validated individually.
+ */
+@Getter
+@ToString
+@EqualsAndHashCode(callSuper = false)
+public class AxContextSchemas extends AxConcept implements AxConceptGetter<AxContextSchema> {
+ private static final long serialVersionUID = -3203734282886453582L;
+
+ private AxArtifactKey key;
+
+ @Getter(AccessLevel.NONE)
+ private Map<AxArtifactKey, AxContextSchema> schemas;
+
+ /**
+ * The Default Constructor creates a {@link AxContextSchemas} object with a null artifact key and creates an empty
+ * context schemas map.
+ */
+ public AxContextSchemas() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextSchemas(final AxContextSchemas copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxContextSchemas} object with the given artifact key and creates an empty
+ * context schemas map.
+ *
+ * @param key the key of the context album container
+ */
+ public AxContextSchemas(final AxArtifactKey key) {
+ this(key, new TreeMap<>());
+ }
+
+ /**
+ * This Constructor creates a {@link AxContextSchemas} object with all its fields defined.
+ *
+ * @param key the key of the context schema container
+ * @param schemas a map of the schemas to insert in the context schema container
+ */
+ public AxContextSchemas(final AxArtifactKey key, final Map<AxArtifactKey, AxContextSchema> schemas) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+
+ this.key = key;
+ this.schemas = new TreeMap<>();
+ this.schemas.putAll(schemas);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.addAll(schemas.keySet());
+
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void buildReferences() {
+ schemas.values().stream().forEach(schema -> schema.buildReferences());
+ }
+
+ /**
+ * Sets the key of the context schema container.
+ *
+ * @param key the key of the container
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the map of context schemas in this container.
+ *
+ * @return the map of schemas
+ */
+ public Map<AxArtifactKey, AxContextSchema> getSchemasMap() {
+ return schemas;
+ }
+
+ /**
+ * Sets the map of context schemas in this container.
+ *
+ * @param schemasMap the map of schemas
+ */
+ public void setSchemasMap(final Map<AxArtifactKey, AxContextSchema> schemasMap) {
+ Assertions.argumentNotNull(schemasMap, "schemasMap may not be null");
+
+ this.schemas = new TreeMap<>();
+ this.schemas.putAll(schemasMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (schemas.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "contextSchemas may not be empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxContextSchema> contextSchemaEntry : schemas.entrySet()) {
+ if (contextSchemaEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on schemas entry " + contextSchemaEntry.getKey()
+ + " may not be the null key"));
+ } else if (contextSchemaEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on schemas entry " + contextSchemaEntry.getKey() + " may not be null"));
+ } else {
+ if (!contextSchemaEntry.getKey().equals(contextSchemaEntry.getValue().getKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on schemas entry " + contextSchemaEntry.getKey()
+ + " does not equal entry key "
+ + contextSchemaEntry.getValue().getKey()));
+ }
+
+ result = contextSchemaEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxContextSchema> contextSchemaEntry : schemas.entrySet()) {
+ contextSchemaEntry.getKey().clean();
+ contextSchemaEntry.getValue().clean();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextSchemas.class);
+
+ final AxContextSchemas copy = ((AxContextSchemas) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+
+ final Map<AxArtifactKey, AxContextSchema> newcontextSchemas = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxContextSchema> contextSchemasEntry : schemas.entrySet()) {
+ newcontextSchemas.put(new AxArtifactKey(contextSchemasEntry.getKey()),
+ new AxContextSchema(contextSchemasEntry.getValue()));
+ }
+ copy.setSchemasMap(newcontextSchemas);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextSchemas other = (AxContextSchemas) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!schemas.equals(other.schemas)) {
+ return (schemas.hashCode() - other.schemas.hashCode());
+ }
+
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxContextSchema get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxContextSchema get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxContextSchema get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxContextSchema> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).getAll(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxContextSchema> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/package-info.java b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/package-info.java
new file mode 100644
index 000000000..a7aa3a5ad
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Contains the concepts required to manage context in APEX. It defines the main APEX concepts of Context Schemas and
+ * Context Albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.model.contextmodel.concepts;
diff --git a/model/src/main/java/org/onap/policy/apex/model/contextmodel/handling/ContextComparer.java b/model/src/main/java/org/onap/policy/apex/model/contextmodel/handling/ContextComparer.java
new file mode 100644
index 000000000..7a5ebfd22
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/contextmodel/handling/ContextComparer.java
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference;
+
+/**
+ * This class compares the context in two AxContext objects and returns the differences. The
+ * differences are returned in a {@link KeyedMapDifference} object that contains the left, equal,
+ * and right context schemas or albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextComparer {
+
+ /**
+ * Compare two {@link AxContextAlbums} objects, comparing their context albums one after
+ * another.
+ *
+ * @param left the left context
+ * @param right the right context
+ * @return the difference
+ */
+ public KeyedMapDifference<AxArtifactKey, AxContextAlbum> compare(final AxContextAlbums left,
+ final AxContextAlbums right) {
+ // Find the difference between the AxContext objects
+ return new KeyedMapComparer<AxArtifactKey, AxContextAlbum>().compareMaps(left.getAlbumsMap(),
+ right.getAlbumsMap());
+ }
+
+ /**
+ * Compare two {@link AxContextSchema} objects, comparing their context schemas one after
+ * another.
+ *
+ * @param left the left context
+ * @param right the right context
+ * @return the difference
+ */
+ public KeyedMapDifference<AxArtifactKey, AxContextSchema> compare(final AxContextSchemas left,
+ final AxContextSchemas right) {
+ // Find the difference between the AxContext objects
+ return new KeyedMapComparer<AxArtifactKey, AxContextSchema>().compareMaps(left.getSchemasMap(),
+ right.getSchemasMap());
+ }
+
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/contextmodel/handling/package-info.java b/model/src/main/java/org/onap/policy/apex/model/contextmodel/handling/package-info.java
new file mode 100644
index 000000000..ec1fa893f
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/contextmodel/handling/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Provides some helper classes for handling context, including a utility class for comparing two
+ * context objects.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.contextmodel.handling;
diff --git a/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineModel.java b/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineModel.java
new file mode 100644
index 000000000..1a590a411
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineModel.java
@@ -0,0 +1,338 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.enginemodel.concepts;
+
+import java.text.SimpleDateFormat;
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * A container class for an Apex engine model. This class is a container class that allows an Apex
+ * model to be constructed that contains the current context {@link AxContextModel}, current state
+ * {@link AxEngineState} and current statistics {@link AxEngineStats} of an Apex engine. This model
+ * is used by an Apex engine to pass its current execution state to any system that wishes to query
+ * that information. The time stamp of the engine model is the time at which the state and
+ * statistics of the engine were read.
+ *
+ * <p>Validation checks that the current state {@link AxEngineState} is defined and that the time stamp
+ * is set on the engine model.
+ */
+public class AxEngineModel extends AxContextModel {
+ private static final long serialVersionUID = 6381235864606564046L;
+ private static final int HASH_CODE_PRIME = 32;
+
+ private long timestamp;
+ private AxEngineState state;
+ private AxEngineStats stats;
+
+ /**
+ * The Default Constructor creates an engine model with a null key and all its fields undefined.
+ */
+ public AxEngineModel() {
+ this(new AxArtifactKey());
+ timestamp = -1;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxEngineModel(final AxEngineModel copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates an engine model with the given key and all its fields
+ * undefined.
+ *
+ * @param key the engine model key
+ */
+ public AxEngineModel(final AxArtifactKey key) {
+ this(key, new AxContextSchemas(new AxArtifactKey(key.getName() + "_DataTypes", key.getVersion())),
+ new AxKeyInformation(new AxArtifactKey(key.getName() + "_KeyInfo", key.getVersion())),
+ new AxContextAlbums(new AxArtifactKey(key.getName() + "_Context", key.getVersion())));
+ }
+
+ /**
+ * This Constructor creates an engine model with its context model data types all defined, the
+ * state of the engine model is undefined.
+ *
+ * @param key the engine model key
+ * @param contextSchemas the context schemas used by the engine model
+ * @param keyInformation the key information used by the engine model
+ * @param contextAlbums the context albums used by the engine model
+ */
+ public AxEngineModel(final AxArtifactKey key, final AxContextSchemas contextSchemas,
+ final AxKeyInformation keyInformation, final AxContextAlbums contextAlbums) {
+ this(key, contextSchemas, keyInformation, contextAlbums, AxEngineState.UNDEFINED,
+ new AxEngineStats(new AxReferenceKey(key, "_EngineStats", key.getVersion())));
+ }
+
+ /**
+ * This Constructor creates an engine model with all its fields defined.
+ *
+ * @param key the engine model key
+ * @param contextSchemas the context schemas used by the engine model
+ * @param keyInformation the key information used by the engine model
+ * @param contextAlbums the context albums used by the engine model
+ * @param state the state of the engine in the engine model
+ * @param stats the statistics of the engine in the engine model
+ */
+ public AxEngineModel(final AxArtifactKey key, final AxContextSchemas contextSchemas,
+ final AxKeyInformation keyInformation, final AxContextAlbums contextAlbums, final AxEngineState state,
+ final AxEngineStats stats) {
+ super(key, contextSchemas, contextAlbums, keyInformation);
+ Assertions.argumentNotNull(state, "state may not be null");
+ Assertions.argumentNotNull(stats, "stats may not be null");
+
+ this.state = state;
+ this.stats = stats;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = super.getKeys();
+ keyList.addAll(stats.getKeys());
+ return keyList;
+ }
+
+ /**
+ * Gets the time stamp at which the engine model measurements were taken.
+ *
+ * @return the time stamp at which the engine model measurements were taken
+ */
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * Gets the time stamp at which the engine model measurements were taken as a string.
+ *
+ * @return the time stamp string
+ */
+ public String getTimeStampString() {
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(timestamp);
+ }
+
+ /**
+ * Sets the time stamp at which the engine model measurements were taken.
+ *
+ * @param timestamp the time stamp at which the engine model measurements were taken
+ */
+ public void setTimestamp(final long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * Gets the state of the engine at the time the measurements were taken.
+ *
+ * @return the state of the engine at the time the measurements were taken
+ */
+ public AxEngineState getState() {
+ return state;
+ }
+
+ /**
+ * Sets the state of the engine.
+ *
+ * @param state the state of the engine
+ */
+ public void setState(final AxEngineState state) {
+ Assertions.argumentNotNull(state, "state may not be null");
+ this.state = state;
+ }
+
+ /**
+ * Gets the statistics of the engine at the time the measurements were taken.
+ *
+ * @return the statistics of the engine at the time the measurements were taken
+ */
+ public AxEngineStats getStats() {
+ return stats;
+ }
+
+ /**
+ * Sets the the statistics of the engine.
+ *
+ * @param stats the the statistics of the engine
+ */
+ public void setStats(final AxEngineStats stats) {
+ Assertions.argumentNotNull(stats, "stats may not be null");
+ this.stats = stats;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ result = stats.validate(result);
+
+ if (timestamp == -1) {
+ result.addValidationMessage(new AxValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
+ this.getClass().getSimpleName() + " - timestamp is not set"));
+ }
+
+ if (state == AxEngineState.UNDEFINED) {
+ result.addValidationMessage(new AxValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
+ this.getClass().getSimpleName() + " - state is UNDEFINED"));
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ super.clean();
+ stats.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append(super.toString());
+ builder.append(",timestamp=");
+ builder.append(timestamp);
+ builder.append(",state=");
+ builder.append(state);
+ builder.append(",stats=");
+ builder.append(stats);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxEngineModel.class);
+
+ final AxEngineModel copy = ((AxEngineModel) copyObject);
+ super.copyTo(targetObject);
+ copy.timestamp = timestamp;
+ copy.setState(state);
+ copy.setStats(new AxEngineStats(stats));
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + super.hashCode();
+ result = prime * result + (int) (timestamp ^ (timestamp >>> HASH_CODE_PRIME));
+ result = prime * result + state.hashCode();
+ result = prime * result + stats.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ throw new IllegalArgumentException("comparison object may not be null");
+ }
+
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxEngineModel other = (AxEngineModel) obj;
+ if (!super.equals(other)) {
+ return false;
+ }
+ if (timestamp != other.timestamp) {
+ return false;
+ }
+ if (!state.equals(other.state)) {
+ return false;
+ }
+ return stats.equals(other.stats);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxEngineModel other = (AxEngineModel) otherObj;
+ if (!super.equals(other)) {
+ return super.compareTo(other);
+ }
+ if (timestamp != other.timestamp) {
+ return (int) (timestamp - other.timestamp);
+ }
+ if (!state.equals(other.state)) {
+ return state.compareTo(other.state);
+ }
+ return stats.compareTo(other.stats);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineState.java b/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineState.java
new file mode 100644
index 000000000..24c564b96
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineState.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2022 Bell Canada. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.enginemodel.concepts;
+
+/**
+ * This enumeration indicates the execution state of an Apex engine.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+public enum AxEngineState {
+ /** The state of the engine is not known. */
+ UNDEFINED(0),
+ /** The engine is stopped. */
+ STOPPED(1),
+ /** The engine is running and is waiting to execute a policy. */
+ READY(2),
+ /** The engine is running and is executing a policy. */
+ EXECUTING(3),
+ /** The engine has been ordered to stop and is stopping. */
+ STOPPING(4);
+
+ private final int stateIdentifier;
+
+ AxEngineState(int stateIdentifier) {
+ this.stateIdentifier = stateIdentifier;
+ }
+
+ public int getStateIdentifier() {
+ return stateIdentifier;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineStats.java b/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineStats.java
new file mode 100644
index 000000000..1420d1e0d
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineStats.java
@@ -0,0 +1,533 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.enginemodel.concepts;
+
+import io.prometheus.client.Gauge;
+import io.prometheus.client.Histogram;
+import java.text.SimpleDateFormat;
+import java.util.List;
+import lombok.Getter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.resources.PrometheusUtils;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is a java bean that is used to record statistics on Apex engines as they execute. Statistics on the number
+ * of events, the amount of time taken to execute the last policy, the average policy execution time, the up time of the
+ * engine, and the time stamp of the last engine start are recorded.
+ */
+
+public class AxEngineStats extends AxConcept {
+ private static final long serialVersionUID = -6981129081962785368L;
+ private static final int HASH_CODE_PRIME = 32;
+ static final String ENGINE_INSTANCE_ID = "engine_instance_id";
+ static final Gauge ENGINE_EVENT_EXECUTIONS = Gauge.build().name("engine_event_executions")
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace()).labelNames(ENGINE_INSTANCE_ID)
+ .help("Total number of APEX events processed by the engine.").register();
+ static final Gauge ENGINE_UPTIME = Gauge.build().name("engine_uptime")
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace()).labelNames(ENGINE_INSTANCE_ID)
+ .help("Time elapsed since the engine was started.").register();
+ static final Gauge ENGINE_START_TIMESTAMP = Gauge.build().name("engine_last_start_timestamp_epoch")
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace()).labelNames(ENGINE_INSTANCE_ID)
+ .help("Epoch timestamp of the instance when engine was last started.").register();
+ static final Gauge ENGINE_AVG_EXECUTION_TIME = Gauge.build().name("engine_average_execution_time_seconds")
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace()).labelNames(ENGINE_INSTANCE_ID)
+ .help("Average time taken to execute an APEX policy in seconds.").register();
+ static final Histogram ENGINE_LAST_EXECUTION_TIME = Histogram.build()
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace())
+ .name("engine_last_execution_time").labelNames(ENGINE_INSTANCE_ID)
+ .help("Time taken to execute the last APEX policy in seconds.").register();
+
+ private AxReferenceKey key;
+ private long timeStamp;
+ private long eventCount;
+ private long lastExecutionTime;
+ private double averageExecutionTime;
+ private long upTime;
+
+ @Getter
+ private transient long lastEnterTime;
+ private long lastStart;
+
+ /**
+ * The Default Constructor creates an engine statistics instance with a null key and with all values cleared.
+ */
+ public AxEngineStats() {
+ this(new AxReferenceKey());
+ timeStamp = 0;
+ eventCount = 0;
+ lastExecutionTime = 0;
+ averageExecutionTime = 0;
+ upTime = 0;
+ lastEnterTime = 0;
+ lastStart = 0;
+ initEngineMetricsWithPrometheus();
+ }
+
+ /**
+ * Register the APEX engine metrics with Prometheus.
+ */
+ private void initEngineMetricsWithPrometheus() {
+ var engineId = getKey().getParentArtifactKey().getId();
+ if (engineId.startsWith(AxKey.NULL_KEY_NAME)) {
+ return;
+ }
+ ENGINE_UPTIME.labels(engineId).set(upTime / 1000d);
+ ENGINE_EVENT_EXECUTIONS.labels(engineId).set(this.eventCount);
+ ENGINE_START_TIMESTAMP.labels(engineId).set(this.lastStart);
+ ENGINE_AVG_EXECUTION_TIME.labels(engineId).set(this.averageExecutionTime / 1000d);
+ ENGINE_LAST_EXECUTION_TIME.labels(engineId).observe(this.lastExecutionTime / 1000d);
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxEngineStats(final AxEngineStats copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates an engine statistics instance with the given key and all values cleared.
+ *
+ * @param key the key
+ */
+ public AxEngineStats(final AxReferenceKey key) {
+ this(key, 0, 0, 0, 0, 0, 0);
+ }
+
+ /**
+ * This Constructor creates an engine statistics instance with all its fields set.
+ *
+ * @param key the engine statistics key
+ * @param timeStamp the time stamp at which the statistics were recorded
+ * @param eventCount the number of events processed by the engine
+ * @param lastExecutionTime the amount of time taken to execute the last policy
+ * @param averageExecutionTime the average amount of time taken to execute a policy
+ * @param upTime the time that has elapsed since the policy engine was started
+ * @param lastStart the time at which the policy engine was last started
+ */
+ public AxEngineStats(final AxReferenceKey key, final long timeStamp, final long eventCount,
+ final long lastExecutionTime, final double averageExecutionTime, final long upTime, final long lastStart) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+
+ this.key = key;
+ this.timeStamp = timeStamp;
+ this.eventCount = eventCount;
+ this.lastExecutionTime = lastExecutionTime;
+ this.averageExecutionTime = averageExecutionTime;
+ this.upTime = upTime;
+ this.lastStart = lastStart;
+ initEngineMetricsWithPrometheus();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return key.getKeys();
+ }
+
+ /**
+ * Sets the engine statistics key.
+ *
+ * @param key the engine statistics key
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the time stamp at which the statistics were recorded.
+ *
+ * @return the time stamp at which the statistics were recorded
+ */
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ /**
+ * Gets the time stamp at which the statistics were recorded as a string.
+ *
+ * @return the time stamp at which the statistics were recorded as a string
+ */
+ public String getTimeStampString() {
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(timeStamp);
+ }
+
+ /**
+ * Sets the time stamp at which the statistics were recorded.
+ *
+ * @param timeStamp the time stamp at which the statistics were recorded
+ */
+ public void setTimeStamp(final long timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ /**
+ * Gets the number of events processed by the engine.
+ *
+ * @return the number of events processed by the engine
+ */
+ public long getEventCount() {
+ return eventCount;
+ }
+
+ /**
+ * Sets the number of events processed by the engine.
+ *
+ * @param eventCount the number of events processed by the engine
+ */
+ public void setEventCount(final long eventCount) {
+ this.eventCount = eventCount;
+ ENGINE_EVENT_EXECUTIONS.labels(getKey().getParentArtifactKey().getId())
+ .set(this.eventCount);
+ }
+
+ /**
+ * Gets the amount of time taken to execute the last policy.
+ *
+ * @return the amount of time taken to execute the last policy
+ */
+ public long getLastExecutionTime() {
+ return lastExecutionTime;
+ }
+
+ /**
+ * Sets the amount of time taken to execute the last policy.
+ *
+ * @param lastExecutionTime the amount of time taken to execute the last policy
+ */
+ public void setLastExecutionTime(final long lastExecutionTime) {
+ this.lastExecutionTime = lastExecutionTime;
+ ENGINE_LAST_EXECUTION_TIME.labels(getKey().getParentArtifactKey().getId())
+ .observe(this.lastExecutionTime / 1000d);
+ }
+
+ /**
+ * Gets the average amount of time taken to execute a policy.
+ *
+ * @return the average amount of time taken to execute a policy
+ */
+ public double getAverageExecutionTime() {
+ return averageExecutionTime;
+ }
+
+ /**
+ * Sets the average amount of time taken to execute a policy.
+ *
+ * @param averageExecutionTime the average amount of time taken to execute a policy
+ */
+ public void setAverageExecutionTime(final double averageExecutionTime) {
+ this.averageExecutionTime = averageExecutionTime;
+ ENGINE_AVG_EXECUTION_TIME.labels(getKey().getParentArtifactKey().getId())
+ .set(this.averageExecutionTime / 1000d);
+ }
+
+ /**
+ * Gets the time that has elapsed since the policy engine was started.
+ *
+ * @return the time that has elapsed since the policy engine was started
+ */
+ public long getUpTime() {
+ if (this.getLastStart() != 0) {
+ return upTime + (timeStamp - this.getLastStart());
+ }
+ return upTime;
+ }
+
+ /**
+ * Sets the time that has elapsed since the policy engine was started.
+ *
+ * @param upTime the time that has elapsed since the policy engine was started
+ */
+ public void setUpTime(final long upTime) {
+ this.upTime = upTime;
+ ENGINE_UPTIME.labels(getKey().getParentArtifactKey().getId()).set(this.upTime / 1000d);
+ }
+
+ /**
+ * Sets the time at which the policy engine was last started.
+ *
+ * @param lastStart the time at which the policy engine was last started
+ */
+ private void setLastStart(final long lastStart) {
+ this.lastStart = lastStart;
+ ENGINE_START_TIMESTAMP.labels(getKey().getParentArtifactKey().getId()).set(this.lastStart);
+ }
+
+ /**
+ * Gets the time at which the policy engine was last started.
+ *
+ * @return the time at which the policy engine was last started
+ */
+ public long getLastStart() {
+ return lastStart;
+ }
+
+ /**
+ * Resets all the statistic values to zero.
+ */
+ public synchronized void reset() {
+ timeStamp = 0;
+ eventCount = 0;
+ lastExecutionTime = 0;
+ averageExecutionTime = 0;
+ upTime = 0;
+ lastEnterTime = 0;
+ lastStart = 0;
+ initEngineMetricsWithPrometheus();
+ }
+
+ /**
+ * Updates the statistics when called, used by the Apex engine when it starts executing a policy.
+ *
+ * @param eventkey the key of the event that is being executed
+ */
+ public synchronized void executionEnter(final AxArtifactKey eventkey) {
+ final long now = System.currentTimeMillis();
+ eventCount++;
+ if (eventCount < 0) {
+ eventCount = 2;
+ }
+ lastEnterTime = now;
+ timeStamp = now;
+ ENGINE_EVENT_EXECUTIONS.labels(getKey().getParentArtifactKey().getId()).set(this.eventCount);
+ }
+
+ /**
+ * Updates the statistics when called, used by the Apex engine when it completes executing a policy.
+ */
+ public synchronized void executionExit() {
+ final long now = System.currentTimeMillis();
+ lastExecutionTime = now - lastEnterTime;
+ ENGINE_LAST_EXECUTION_TIME.labels(getKey().getParentArtifactKey().getId())
+ .observe(this.lastExecutionTime / 1000d);
+
+ averageExecutionTime = ((averageExecutionTime * (eventCount - 1.0)) + lastExecutionTime) / eventCount;
+ lastEnterTime = 0;
+ timeStamp = System.currentTimeMillis();
+ ENGINE_AVG_EXECUTION_TIME.labels(getKey().getParentArtifactKey().getId())
+ .set(this.averageExecutionTime / 1000d);
+ }
+
+ /**
+ * Updates the statistics when called, used by the Apex engine when it is started.
+ */
+ public synchronized void engineStart() {
+ final long now = System.currentTimeMillis();
+ timeStamp = now;
+ this.setLastStart(now);
+ }
+
+ /**
+ * Updates the statistics when called, used by the Apex engine when it is stopped.
+ */
+ public synchronized void engineStop() {
+ final long now = System.currentTimeMillis();
+ timeStamp = now;
+ upTime += (timeStamp - this.getLastStart());
+ this.setLastStart(0);
+ ENGINE_UPTIME.labels(getKey().getParentArtifactKey().getId()).set(this.upTime / 1000d);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult result) {
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ return key.validate(result);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("engineKey=");
+ builder.append(key);
+ builder.append(",timeStamp=");
+ builder.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(timeStamp));
+ builder.append(",eventCount=");
+ builder.append(eventCount);
+ builder.append(",lastExecutionTime=");
+ builder.append(lastExecutionTime);
+ builder.append(",averageExecutionTime=");
+ builder.append(averageExecutionTime);
+ builder.append(",upTime=");
+ builder.append(getUpTime());
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxEngineStats.class);
+
+ final AxEngineStats copy = ((AxEngineStats) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setTimeStamp(timeStamp);
+ copy.setEventCount(eventCount);
+ copy.setLastExecutionTime(lastExecutionTime);
+ copy.setAverageExecutionTime(averageExecutionTime);
+ copy.setUpTime(upTime);
+ copy.setLastStart(lastStart);
+ initEngineMetricsWithPrometheus();
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + (int) (timeStamp ^ (timeStamp >>> HASH_CODE_PRIME));
+ result = prime * result + (int) (eventCount ^ (eventCount >>> HASH_CODE_PRIME));
+ result = prime * result + (int) (lastExecutionTime ^ (lastExecutionTime >>> HASH_CODE_PRIME));
+ result = prime * result + ((int) averageExecutionTime ^ ((int) averageExecutionTime >>> HASH_CODE_PRIME));
+ result = prime * result + (int) (upTime ^ (upTime >>> HASH_CODE_PRIME));
+ result = prime * result + (int) (getLastStart() ^ (getLastStart() >>> HASH_CODE_PRIME));
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxEngineStats other = (AxEngineStats) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (timeStamp != other.timeStamp) {
+ return false;
+ }
+ if (eventCount != other.eventCount) {
+ return false;
+ }
+ if (lastExecutionTime != other.lastExecutionTime) {
+ return false;
+ }
+ if (Double.compare(averageExecutionTime, other.averageExecutionTime) != 0) {
+ return false;
+ }
+ if (upTime != other.upTime) {
+ return false;
+ }
+ return getLastStart() == other.getLastStart();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxEngineStats other = (AxEngineStats) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (timeStamp != other.timeStamp) {
+ return (int) (timeStamp - other.timeStamp);
+ }
+ if (eventCount != other.eventCount) {
+ return (int) (eventCount - other.eventCount);
+ }
+ if (lastExecutionTime != other.lastExecutionTime) {
+ return (int) (lastExecutionTime - other.lastExecutionTime);
+ }
+ final int result = Double.compare(averageExecutionTime, other.averageExecutionTime);
+ if (result != 0) {
+ return result;
+ }
+ if (upTime != other.upTime) {
+ return (int) (upTime - other.upTime);
+ }
+
+ return Long.compare(lastStart, other.lastStart);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/package-info.java b/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/package-info.java
new file mode 100644
index 000000000..4557af7db
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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=========================================================
+ */
+
+/**
+ * Contains the concepts required to receive state information and statistcs from running APEX
+ * engines.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.enginemodel.concepts;
diff --git a/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEvent.java b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEvent.java
new file mode 100644
index 000000000..a4c0e9db1
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEvent.java
@@ -0,0 +1,547 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.eventmodel.concepts;
+
+import com.google.common.base.Strings;
+import com.google.gson.annotations.SerializedName;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.apache.commons.lang3.EnumUtils;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxToscaPolicyProcessingStatus;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class defines an Apex event. An {@link AxEvent} is used to kick off execution of policies in Apex and is emitted
+ * by policies when they complete execution. In addition, Apex uses {@link AxEvent} instances internally to pass
+ * control from one Apex state to the next during execution.
+ *
+ * <p>The {@link AxArtifactKey} of an event uniquely identifies it in an Apex system and the name field in the key is
+ * the name of the event.
+ *
+ * <p>Each {@link AxEvent} has a name space, which is usually set to identify the domain of application of an event. For
+ * example a 4G cell power event might have the name space {@code org.onap.radio.4g} and the name {@code PowerEvent}.
+ * The source and target of the event are reserved to hold an identifier that defines the sender and receiver of an
+ * event respectively. The definition and structure of these fields is reserved for future use and their use by
+ * applications is currently not recommended.
+ *
+ * <p>The parameters that an event has are defined as a map of {@link AxField} instances.
+ *
+ * <p>Validation checks that the event key is valid. If name space is a blank string, a warning is issued. Blank source
+ * or target fields result in observations being issued. An event may not have any parameters. If it has parameters, the
+ * name and value of each parameter entry is checked to ensure they are not null. Then the local name of each parameter
+ * is checked to ensure it matches the event parameter key on the event. Finally, the parent key of each parameter is
+ * checked to ensure it matches the event key.
+ */
+public class AxEvent extends AxConcept {
+ private static final long serialVersionUID = -1460388382582984269L;
+
+ private static final String WHITESPACE_REGEXP = "\\s+$";
+
+ /** The key of the event, unique in the Apex system. */
+ // CHECKSTYLE:OFF: checkstyle:VisibilityMonitor
+ protected AxArtifactKey key;
+ // CHECKSTYLE:ON: checkstyle:VisibilityMonitor
+
+ private String nameSpace;
+ private String source;
+ private String target;
+
+ @SerializedName("parameter")
+ private Map<String, AxField> parameterMap;
+ private String toscaPolicyState;
+
+ /**
+ * The default constructor creates an event with a null artifact key. The event name space, source, and target are
+ * all defined as empty strings and the parameter map is initialized as an empty map.
+ */
+ public AxEvent() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxEvent(final AxEvent copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The default constructor creates an event with the given artifact key. The event name space, source, and target
+ * are all defined as empty strings and the parameter map is initialized as an empty map.
+ *
+ * @param key the key of the event
+ */
+ public AxEvent(final AxArtifactKey key) {
+ this(key, "", "", "", new TreeMap<>(), "");
+ }
+
+ /**
+ * This constructor creates an event with the given artifact key and name space. The event source, and target are
+ * all defined as empty strings and the parameter map is initialized as an empty map.
+ *
+ * @param key the key of the event
+ * @param nameSpace the name space of the event
+ */
+ public AxEvent(final AxArtifactKey key, final String nameSpace) {
+ this(key, nameSpace, "", "", new TreeMap<>(), "");
+ }
+
+ /**
+ * This constructor creates an event with the given artifact key, name space, source and target. The parameter map
+ * is initialized as an empty map.
+ *
+ * @param key the key of the event
+ * @param nameSpace the name space of the event
+ * @param source the source of the event
+ * @param target the target of the event
+ */
+ public AxEvent(final AxArtifactKey key, final String nameSpace, final String source, final String target) {
+ this(key, nameSpace, source, target, new TreeMap<>(), "");
+ }
+
+ /**
+ * This constructor creates an event with all its fields defined.
+ *
+ * @param key the key of the event
+ * @param nameSpace the name space of the event
+ * @param source the source of the event
+ * @param target the target of the event
+ * @param parameterMap the map of parameters that the event has
+ * @param toscaPolicyState the TOSCA policy processing status that event is flagged with
+ */
+ public AxEvent(final AxArtifactKey key, final String nameSpace, final String source, final String target,
+ final SortedMap<String, AxField> parameterMap, final String toscaPolicyState) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(nameSpace, "nameSpace may not be null");
+ Assertions.argumentNotNull(source, "source may not be null");
+ Assertions.argumentNotNull(target, "target may not be null");
+ Assertions.argumentNotNull(parameterMap, "parameterMap may not be null");
+
+ this.key = key;
+ this.nameSpace = nameSpace;
+ this.source = source;
+ this.target = target;
+ this.parameterMap = parameterMap;
+ this.toscaPolicyState = toscaPolicyState;
+ }
+
+ /**
+ * This method checks that an event has all the fields in the {@code otherFieldSet} set defined on it.
+ *
+ * @param otherFieldSet the set of fields to check for existence on this event
+ * @return true, if all the {@code otherFieldSet} fields are defined on this event
+ */
+ public boolean hasFields(final Set<AxField> otherFieldSet) {
+ return parameterMap.values().containsAll(otherFieldSet);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void buildReferences() {
+ for (final AxField parameter : parameterMap.values()) {
+ parameter.getKey().setParentArtifactKey(key);
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ for (final AxField field : parameterMap.values()) {
+ keyList.addAll(field.getKeys());
+ }
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the event.
+ *
+ * @param key the key of the event
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+
+ for (final AxField parameter : parameterMap.values()) {
+ parameter.getKey().setParentArtifactKey(key);
+ }
+ }
+
+ /**
+ * Gets the name space of the event.
+ *
+ * @return the name space of the event
+ */
+ public String getNameSpace() {
+ return nameSpace;
+ }
+
+ /**
+ * Sets the name space of the event.
+ *
+ * @param nameSpace the name space of the event
+ */
+ public void setNameSpace(final String nameSpace) {
+ Assertions.argumentNotNull(nameSpace, "nameSpace may not be null");
+ this.nameSpace = nameSpace.trim();
+ }
+
+ /**
+ * Gets the source of the event.
+ *
+ * @return the source of the event
+ */
+ public String getSource() {
+ return source;
+ }
+
+ /**
+ * Sets the source of the event.
+ *
+ * @param source the source of the event
+ */
+ public void setSource(final String source) {
+ Assertions.argumentNotNull(source, "source may not be null");
+ this.source = source.trim();
+ }
+
+ /**
+ * Gets the target of the event.
+ *
+ * @return the target of the event
+ */
+ public String getTarget() {
+ return target;
+ }
+
+ /**
+ * Sets the target of the event.
+ *
+ * @param target the target of the event
+ */
+ public void setTarget(final String target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+ this.target = target.trim();
+ }
+
+ /**
+ * Gets the event parameter map.
+ *
+ * @return the event parameter map
+ */
+ public Map<String, AxField> getParameterMap() {
+ return parameterMap;
+ }
+
+ /**
+ * Gets the fields defined on the event as a set.
+ *
+ * @return the fields defined on the event as a set
+ */
+ public Set<AxField> getFields() {
+ return new TreeSet<>(parameterMap.values());
+ }
+
+ /**
+ * Sets the event parameter map, containing all the fields of the event.
+ *
+ * @param parameterMap the event parameter map
+ */
+ public void setParameterMap(final Map<String, AxField> parameterMap) {
+ Assertions.argumentNotNull(parameterMap, "parameterMap may not be null");
+ this.parameterMap = parameterMap;
+ }
+
+ /**
+ * Gets the TOSCA policy processing status from the event.
+ *
+ * @return the TOSCA policy processing status
+ */
+ public String getToscaPolicyState() {
+ return toscaPolicyState;
+ }
+
+ /**
+ * Sets the TOSCA policy processing status on the event.
+ *
+ * @param toscaPolicyState the TOSCA policy processing status
+ */
+ public void setToscaPolicyState(String toscaPolicyState) {
+ this.toscaPolicyState = toscaPolicyState;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (nameSpace.replaceAll(WHITESPACE_REGEXP, "").length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.WARNING,
+ "nameSpace on event is blank"));
+ }
+
+ if (source.replaceAll(WHITESPACE_REGEXP, "").length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "source on event is blank"));
+ }
+
+ if (target.replaceAll(WHITESPACE_REGEXP, "").length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "target on event is blank"));
+ }
+
+ for (final Entry<String, AxField> eventParameterEntry : parameterMap.entrySet()) {
+ if (eventParameterEntry.getKey() == null || eventParameterEntry.getKey().equals(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on parameter " + eventParameterEntry.getKey() + " may not be the null key"));
+ } else if (eventParameterEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on parameter " + eventParameterEntry.getKey() + " may not be null"));
+ } else {
+ result = validateEventParameters(eventParameterEntry, result);
+ }
+ }
+
+ if (!Strings.isNullOrEmpty(toscaPolicyState)
+ && !EnumUtils.isValidEnum(AxToscaPolicyProcessingStatus.class, toscaPolicyState)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "toscaPolicyState on event is not a valid enum. Valid values are: "
+ + Arrays.asList(AxToscaPolicyProcessingStatus.values())));
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate an event parameter entry.
+ *
+ * @param eventParameterEntry the event parameter entry
+ * @param result the validation result to append to
+ * @return The validation result
+ */
+ private AxValidationResult validateEventParameters(final Entry<String, AxField> eventParameterEntry,
+ final AxValidationResult result) {
+ if (!eventParameterEntry.getKey().equals(eventParameterEntry.getValue().getKey().getLocalName())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on parameter " + eventParameterEntry.getKey()
+ + " does not equal parameter field local name "
+ + eventParameterEntry.getValue().getKey().getLocalName()));
+ }
+
+ if (!eventParameterEntry.getValue().getKey().getParentArtifactKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent key on parameter field " + eventParameterEntry.getValue().getKey()
+ + " does not equal event key"));
+ }
+
+ return eventParameterEntry.getValue().validate(result);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ nameSpace = nameSpace.trim();
+ source = source.trim();
+ target = target.trim();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",nameSpace=");
+ builder.append(nameSpace);
+ builder.append(",source=");
+ builder.append(source);
+ builder.append(",target=");
+ builder.append(target);
+ builder.append(",parameter=");
+ builder.append(parameterMap);
+ builder.append(",toscaPolicyState=");
+ builder.append(toscaPolicyState);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "targetObject may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxEvent.class);
+
+ final AxEvent copy = (AxEvent) copyObject;
+
+ final Map<String, AxField> newParameterMap = new TreeMap<>();
+ for (final Entry<String, AxField> eventParameterMapEntry : parameterMap.entrySet()) {
+ newParameterMap.put(eventParameterMapEntry.getKey(), new AxField(eventParameterMapEntry.getValue()));
+ }
+ copy.setParameterMap(newParameterMap);
+
+ copy.setKey(new AxArtifactKey(key));
+ copy.setNameSpace(nameSpace);
+ copy.setSource(source);
+ copy.setTarget(target);
+ copy.setToscaPolicyState(toscaPolicyState);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + nameSpace.hashCode();
+ result = prime * result + source.hashCode();
+ result = prime * result + target.hashCode();
+ result = prime * result + parameterMap.hashCode();
+ result = prime * result + toscaPolicyState.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxEvent other = (AxEvent) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!nameSpace.equals(other.nameSpace)) {
+ return false;
+ }
+ if (!source.equals(other.source)) {
+ return false;
+ }
+ if (!target.equals(other.target)) {
+ return false;
+ }
+ if (!toscaPolicyState.equals(other.toscaPolicyState)) {
+ return false;
+ }
+ return parameterMap.equals(other.parameterMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxEvent other = (AxEvent) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!nameSpace.equals(other.nameSpace)) {
+ return nameSpace.compareTo(other.nameSpace);
+ }
+ if (!source.equals(other.source)) {
+ return source.compareTo(other.source);
+ }
+ if (!target.equals(other.target)) {
+ return target.compareTo(other.target);
+ }
+ if (!parameterMap.equals(other.parameterMap)) {
+ return (parameterMap.hashCode() - other.parameterMap.hashCode());
+ }
+ if (!toscaPolicyState.equals(other.toscaPolicyState)) {
+ return toscaPolicyState.compareTo(other.toscaPolicyState);
+ }
+
+ return 0;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEventModel.java b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEventModel.java
new file mode 100644
index 000000000..b91712c9d
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEventModel.java
@@ -0,0 +1,276 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.eventmodel.concepts;
+
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * A container class for an Apex event model. This class is a container class that allows an Apex model to be
+ * constructed that contains events and context and the key information for those events and context. The model contains
+ * schema definitions and the definitions of events that use those schemas.
+ *
+ * <p>Validation runs {@link AxModel} validation on the model. In addition, the {@link AxContextSchemas} and
+ * {@link AxEvents} validation is run on the context schemas and events in the model.
+ */
+public class AxEventModel extends AxModel {
+ private static final long serialVersionUID = 8800599637708309945L;
+
+ private AxContextSchemas schemas;
+ private AxEvents events;
+
+ /**
+ * The Default Constructor creates a {@link AxEventModel} object with a null artifact key and creates an empty event
+ * model.
+ */
+ public AxEventModel() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxEventModel(final AxEventModel copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxEventModel} object with the given artifact key and creates an empty event
+ * model.
+ *
+ * @param key the event model key
+ */
+ public AxEventModel(final AxArtifactKey key) {
+ this(key, new AxContextSchemas(new AxArtifactKey(key.getName() + "_Schemas", key.getVersion())),
+ new AxKeyInformation(new AxArtifactKey(key.getName() + "_KeyInfo", key.getVersion())),
+ new AxEvents(new AxArtifactKey(key.getName() + "_Events", key.getVersion())));
+ }
+
+ /**
+ * Constructor that initiates a {@link AxEventModel} with all its fields.
+ *
+ * @param key the event model key
+ * @param schemas the schemas for events in the event model
+ * @param keyInformation the key information for context schemas and events in the event model
+ * @param events the events in the event model
+ */
+ public AxEventModel(final AxArtifactKey key, final AxContextSchemas schemas, final AxKeyInformation keyInformation,
+ final AxEvents events) {
+ super(key, keyInformation);
+ Assertions.argumentNotNull(events, "events may not be null");
+
+ this.schemas = schemas;
+ this.events = events;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void register() {
+ super.register();
+ ModelService.registerModel(AxContextSchemas.class, getSchemas());
+ ModelService.registerModel(AxEvents.class, getEvents());
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = super.getKeys();
+
+ keyList.addAll(schemas.getKeys());
+ keyList.addAll(events.getKeys());
+
+ return keyList;
+ }
+
+ /**
+ * Gets the context schemas.
+ *
+ * @return the context schemas
+ */
+ public AxContextSchemas getSchemas() {
+ return schemas;
+ }
+
+ /**
+ * Sets the context schemas.
+ *
+ * @param schemas the context schemas
+ */
+ public void setSchemas(final AxContextSchemas schemas) {
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ this.schemas = schemas;
+ }
+
+ /**
+ * Gets the events from the model.
+ *
+ * @return the events
+ */
+ public AxEvents getEvents() {
+ return events;
+ }
+
+ /**
+ * Sets the events in the model.
+ *
+ * @param events the events
+ */
+ public void setEvents(final AxEvents events) {
+ Assertions.argumentNotNull(events, "events may not be null");
+ this.events = events;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ result = super.validate(result);
+ result = schemas.validate(result);
+ return events.validate(result);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ super.clean();
+ schemas.clean();
+ events.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append(super.toString());
+ builder.append(",schemas=");
+ builder.append(schemas);
+ builder.append(",events=");
+ builder.append(events);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxEventModel.class);
+
+ final AxEventModel copy = ((AxEventModel) copyObject);
+ super.copyTo(targetObject);
+ copy.setSchemas(new AxContextSchemas(schemas));
+ copy.setEvents(new AxEvents(events));
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + super.hashCode();
+ result = prime * result + schemas.hashCode();
+ result = prime * result + events.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ throw new IllegalArgumentException("comparison object may not be null");
+ }
+
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxEventModel other = (AxEventModel) obj;
+ if (!super.equals(other)) {
+ return false;
+ }
+ if (!schemas.equals(other.schemas)) {
+ return false;
+ }
+ return events.equals(other.events);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxEventModel other = (AxEventModel) otherObj;
+ if (!super.equals(other)) {
+ return super.compareTo(other);
+ }
+ if (!schemas.equals(other.schemas)) {
+ return schemas.compareTo(other.schemas);
+ }
+ return events.compareTo(other.events);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEvents.java b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEvents.java
new file mode 100644
index 000000000..aac1562de
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEvents.java
@@ -0,0 +1,351 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,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.onap.policy.apex.model.eventmodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is an event container and holds a map of the events for an entire Apex model. All Apex models that use
+ * events must have an {@link AxEvents} field. The {@link AxEvents} class implements the helper methods of the
+ * {@link AxConceptGetter} interface to allow {@link AxEvents} instances to be retrieved by calling methods directly on
+ * this class without referencing the contained map.
+ *
+ * <p>Validation checks that the container key is not null. An error is issued if no events are defined in the
+ * container. Each event entry is checked to ensure that its key and value are not null and that the key matches the key
+ * in the map value. Each event entry is then validated individually.
+ */
+public class AxEvents extends AxConcept implements AxConceptGetter<AxEvent> {
+ private static final long serialVersionUID = 4290442590545820316L;
+
+ private AxArtifactKey key;
+ private Map<AxArtifactKey, AxEvent> eventMap;
+
+ /**
+ * The Default Constructor creates a {@link AxEvents} object with a null artifact key and creates an empty event
+ * map.
+ */
+ public AxEvents() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxEvents(final AxEvents copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxEvents} object with the given artifact key and creates an empty event map.
+ *
+ * @param key the event container key
+ */
+ public AxEvents(final AxArtifactKey key) {
+ this(key, new TreeMap<>());
+ }
+
+ /**
+ * This Constructor creates an event container with all of its fields defined.
+ *
+ * @param key the event container key
+ * @param eventMap the events to be stored in the event container
+ */
+ public AxEvents(final AxArtifactKey key, final Map<AxArtifactKey, AxEvent> eventMap) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(eventMap, "eventMap may not be null");
+
+ this.key = key;
+ this.eventMap = new TreeMap<>();
+ this.eventMap.putAll(eventMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ for (final AxEvent event : eventMap.values()) {
+ keyList.addAll(event.getKeys());
+ }
+
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void buildReferences() {
+ eventMap.values().stream().forEach(event -> event.buildReferences());
+ }
+
+ /**
+ * Sets the key of the event container.
+ *
+ * @param key the event container key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the event map containing the events in the event container.
+ *
+ * @return the event map with all the events in the event container
+ */
+ public Map<AxArtifactKey, AxEvent> getEventMap() {
+ return eventMap;
+ }
+
+ /**
+ * Sets the event map containing the events in the event container.
+ *
+ * @param eventMap the event map containing the events in the event container
+ */
+ public void setEventMap(final Map<AxArtifactKey, AxEvent> eventMap) {
+ Assertions.argumentNotNull(eventMap, "eventMap may not be null");
+ this.eventMap = new TreeMap<>();
+ this.eventMap.putAll(eventMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (eventMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "eventMap may not be empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxEvent> eventEntry : eventMap.entrySet()) {
+ if (eventEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on event entry " + eventEntry.getKey() + " may not be the null key"));
+ } else if (eventEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on event entry " + eventEntry.getKey() + " may not be null"));
+ } else {
+ if (!eventEntry.getKey().equals(eventEntry.getValue().getKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on event entry key " + eventEntry.getKey()
+ + " does not equal event value key "
+ + eventEntry.getValue().getKey()));
+ }
+
+ result = eventEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxEvent> eventEntry : eventMap.entrySet()) {
+ eventEntry.getKey().clean();
+ eventEntry.getValue().clean();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",eventMap=");
+ builder.append(eventMap);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxEvents.class);
+
+ final AxEvents copy = (AxEvents) copyObject;
+ copy.setKey(new AxArtifactKey(key));
+ final Map<AxArtifactKey, AxEvent> newEventMap = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxEvent> eventMapEntry : eventMap.entrySet()) {
+ newEventMap.put(new AxArtifactKey(eventMapEntry.getKey()), new AxEvent(eventMapEntry.getValue()));
+ }
+ copy.setEventMap(newEventMap);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + eventMap.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxEvents other = (AxEvents) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return eventMap.equals(other.eventMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxEvents other = (AxEvents) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!eventMap.equals(other.eventMap)) {
+ return (eventMap.hashCode() - other.eventMap.hashCode());
+ }
+
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxEvent get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxEvent>) eventMap).get(conceptKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxEvent get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxEvent>) eventMap).get(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxEvent get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxEvent>) eventMap).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxEvent> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxEvent>) eventMap).getAll(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxEvent> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxEvent>) eventMap).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxField.java b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxField.java
new file mode 100644
index 000000000..26511c9d1
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxField.java
@@ -0,0 +1,347 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.eventmodel.concepts;
+
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * In Apex, a field is an input or output parameter to or from a concept. For example, the parameters of an event are
+ * fields and the input and output of a task is defined as a collection of fields.
+ *
+ * <p>A field has an {@link AxReferenceKey} key that defines its name and parent, and a {@link AxArtifactKey} key to a
+ * context schema that defines the structure of the data atom that holds the value of the field. Fields can be specified
+ * as being optional but are mandatory by default.
+ *
+ * <p>Validation checks that the field key and the field schema reference key are not null.
+ */
+public class AxField extends AxConcept {
+ private static final String KEY_MAY_NOT_BE_NULL = "key may not be null";
+ private static final String FIELD_SCHEMA_KEY_MAY_NOT_BE_NULL = "fieldSchemaKey may not be null";
+
+ private static final long serialVersionUID = -6443016863162692288L;
+
+ private static final int HASH_PRIME_0 = 1231;
+ private static final int HASH_PRIME_1 = 1237;
+
+ private AxReferenceKey key;
+ private AxArtifactKey fieldSchemaKey;
+ private boolean optional;
+
+ /**
+ * The default constructor creates a field with a null artifact and schema key.
+ */
+ public AxField() {
+ this(new AxReferenceKey());
+ optional = false;
+ }
+
+ /**
+ * The default constructor creates a field with the given artifact key and a null schema key.
+ *
+ * @param key the field key
+ */
+ public AxField(final AxReferenceKey key) {
+ this(key, new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxField(final AxField copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor to create the field with both its keys defined.
+ *
+ * @param key the field key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ */
+ public AxField(final AxReferenceKey key, final AxArtifactKey fieldSchemaKey) {
+ super();
+ Assertions.argumentNotNull(key, KEY_MAY_NOT_BE_NULL);
+ Assertions.argumentNotNull(fieldSchemaKey, FIELD_SCHEMA_KEY_MAY_NOT_BE_NULL);
+
+ this.key = key;
+ this.fieldSchemaKey = fieldSchemaKey;
+ }
+
+ /**
+ * Constructor to create the field with all its fields defined.
+ *
+ * @param key the field key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ * @param optional true if this field is optional
+ */
+ public AxField(final AxReferenceKey key, final AxArtifactKey fieldSchemaKey, final boolean optional) {
+ super();
+ Assertions.argumentNotNull(key, KEY_MAY_NOT_BE_NULL);
+ Assertions.argumentNotNull(fieldSchemaKey, FIELD_SCHEMA_KEY_MAY_NOT_BE_NULL);
+
+ this.key = key;
+ this.fieldSchemaKey = fieldSchemaKey;
+ this.optional = optional;
+ }
+
+ /**
+ * Constructor to create the field with the local name of its reference key defined and its schema key defined.
+ *
+ * @param localName the local name of the field reference key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ */
+ public AxField(final String localName, final AxArtifactKey fieldSchemaKey) {
+ super();
+ Assertions.argumentNotNull(localName, "localName may not be null");
+ Assertions.argumentNotNull(fieldSchemaKey, FIELD_SCHEMA_KEY_MAY_NOT_BE_NULL);
+
+ key = new AxReferenceKey();
+ key.setLocalName(localName);
+ this.fieldSchemaKey = fieldSchemaKey;
+ }
+
+ /**
+ * Constructor to create the field with the local name of its reference key defined, its schema key and optionality
+ * defined.
+ *
+ * @param localName the local name of the field reference key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ * @param optional true if this field is optional
+ */
+ public AxField(final String localName, final AxArtifactKey fieldSchemaKey, final boolean optional) {
+ super();
+ Assertions.argumentNotNull(localName, "localName may not be null");
+ Assertions.argumentNotNull(fieldSchemaKey, FIELD_SCHEMA_KEY_MAY_NOT_BE_NULL);
+
+ key = new AxReferenceKey();
+ key.setLocalName(localName);
+ this.fieldSchemaKey = fieldSchemaKey;
+ this.optional = optional;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.add(new AxKeyUse(fieldSchemaKey));
+ return keyList;
+ }
+
+ /**
+ * Sets the reference key of the field.
+ *
+ * @param key the field reference key
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, KEY_MAY_NOT_BE_NULL);
+ this.key = key;
+ }
+
+ /**
+ * Gets the key of the field schema.
+ *
+ * @return the field schema key
+ */
+ public AxArtifactKey getSchema() {
+ return fieldSchemaKey;
+ }
+
+ /**
+ * Sets the key of the field schema.
+ *
+ * @param schema the field schema key
+ */
+ public void setSchema(final AxArtifactKey schema) {
+ Assertions.argumentNotNull(schema, "schema may not be null");
+ this.fieldSchemaKey = schema;
+ }
+
+ /**
+ * Gets the optionality of the field.
+ *
+ * @return the field optional flag
+ */
+ public boolean getOptional() {
+ return optional;
+ }
+
+ /**
+ * Sets the optionality of the field.
+ *
+ * @param optional the optionality of the field
+ */
+ public void setOptional(final boolean optional) {
+ this.optional = optional;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (fieldSchemaKey.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "fieldSchemaKey is a null key: " + fieldSchemaKey));
+ }
+ return fieldSchemaKey.validate(result);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ fieldSchemaKey.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",fieldSchemaKey=");
+ builder.append(fieldSchemaKey);
+ builder.append(",optional=");
+ builder.append(optional);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxField.class);
+
+ final AxField copy = ((AxField) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setSchema(new AxArtifactKey(fieldSchemaKey));
+ copy.setOptional(optional);
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + fieldSchemaKey.hashCode();
+ result = prime * result + (optional ? HASH_PRIME_0 : HASH_PRIME_1);
+ return result;
+ }
+
+ /*
+ * (nonJavadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (!(obj instanceof AxField)) {
+ return false;
+ }
+
+ final AxField other = (AxField) obj;
+ if (!key.getLocalName().equals(other.key.getLocalName())) {
+ return false;
+ }
+ if (optional != other.optional) {
+ return false;
+ }
+ return fieldSchemaKey.equals(other.fieldSchemaKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return 1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (!(otherObj instanceof AxField)) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxField other = (AxField) otherObj;
+ if (!key.getLocalName().equals(other.key.getLocalName())) {
+ return key.getLocalName().compareTo(other.key.getLocalName());
+ }
+ if (optional != other.optional) {
+ return (optional ? 1 : -1);
+ }
+ return fieldSchemaKey.compareTo(other.fieldSchemaKey);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxInputField.java b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxInputField.java
new file mode 100644
index 000000000..6155c7186
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxInputField.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.eventmodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+/**
+ * This class specializes the {@link AxField} class for use as input fields on events.
+ */
+public class AxInputField extends AxField {
+ private static final long serialVersionUID = 2090324845463750391L;
+
+ /**
+ * The default constructor creates a field with a null artifact and schema key.
+ */
+ public AxInputField() {
+ super();
+ }
+
+ /**
+ * The default constructor creates a field with the given artifact key and a null schema key.
+ *
+ * @param key the field key
+ */
+ public AxInputField(final AxReferenceKey key) {
+ super(key);
+ }
+
+ /**
+ * Constructor to create the field with both its keys defined.
+ *
+ * @param key the field key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ */
+ public AxInputField(final AxReferenceKey key, final AxArtifactKey fieldSchemaKey) {
+ super(key, fieldSchemaKey);
+ }
+
+ /**
+ * Constructor to create the field with both its keys defined and optional flag specified.
+ *
+ * @param key the field key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ * @param optional true if the task field is optional, false otherwise
+ */
+ public AxInputField(final AxReferenceKey key, final AxArtifactKey fieldSchemaKey, final boolean optional) {
+ super(key, fieldSchemaKey, optional);
+ }
+
+ /**
+ * Constructor to create the field with the local name of its reference key defined and its schema key defined.
+ *
+ * @param localName the local name of the field reference key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ */
+ public AxInputField(final String localName, final AxArtifactKey fieldSchemaKey) {
+ super(localName, fieldSchemaKey);
+ }
+
+ /**
+ * Copy constructor, create an input field as a copy of another input field.
+ *
+ * @param field the input field to copy from
+ */
+ public AxInputField(final AxInputField field) {
+ super(new AxReferenceKey(field.getKey()), new AxArtifactKey(field.getSchema()), field.getOptional());
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxOutputField.java b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxOutputField.java
new file mode 100644
index 000000000..7f3437617
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxOutputField.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.eventmodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+/**
+ * This class specializes the {@link AxField} class for use as output fields on events.
+ */
+public class AxOutputField extends AxField {
+ private static final long serialVersionUID = 2090324845463750391L;
+
+ /**
+ * The default constructor creates a field with a null artifact and schema key.
+ */
+ public AxOutputField() {
+ super();
+ }
+
+ /**
+ * The default constructor creates a field with the given artifact key and a null schema key.
+ *
+ * @param key the field key
+ */
+ public AxOutputField(final AxReferenceKey key) {
+ super(key);
+ }
+
+ /**
+ * Constructor to create the field with both its keys defined.
+ *
+ * @param key the field key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ */
+ public AxOutputField(final AxReferenceKey key, final AxArtifactKey fieldSchemaKey) {
+ super(key, fieldSchemaKey);
+ }
+
+ /**
+ * Constructor to create the field with both its keys defined and optional flag specified.
+ *
+ * @param key the field key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ * @param optional true if the task field is optional, false otherwise
+ */
+ public AxOutputField(final AxReferenceKey key, final AxArtifactKey fieldSchemaKey, final boolean optional) {
+ super(key, fieldSchemaKey, optional);
+ }
+
+ /**
+ * Constructor to create the field with the local name of its reference key defined and its schema key defined.
+ *
+ * @param localName the local name of the field reference key
+ * @param fieldSchemaKey the key of the field schema to use for this field
+ */
+ public AxOutputField(final String localName, final AxArtifactKey fieldSchemaKey) {
+ super(localName, fieldSchemaKey);
+ }
+
+ /**
+ * Copy constructor, create an output field as a copy of another output field.
+ *
+ * @param field the output field to copy from
+ */
+ public AxOutputField(final AxOutputField field) {
+ super(new AxReferenceKey(field.getKey()), new AxArtifactKey(field.getSchema()), field.getOptional());
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/package-info.java b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/package-info.java
new file mode 100644
index 000000000..414d22d0e
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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=========================================================
+ */
+
+/**
+ * Contains the concepts required to manage events in APEX. It defines the main Apex concepts of events and fields.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.eventmodel.concepts;
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexApiResult.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexApiResult.java
new file mode 100644
index 000000000..83e3b5370
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexApiResult.java
@@ -0,0 +1,264 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.modelapi;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Setter;
+
+/**
+ * The Class ApexEditorAPIResult return the result of and messages from all model API method calls on the
+ * {@link ApexModel} API.
+ */
+@Setter
+public class ApexApiResult {
+
+ /**
+ * This enumeration is used to represent the result status of a call on the {@link ApexModel} API.
+ */
+ public enum Result {
+ /** The method call succeeded. */
+ SUCCESS,
+ /** The method call succeeded and all operations are now completed. */
+ FINISHED,
+ /** The method call for a create operation failed because the concept already exists. */
+ CONCEPT_EXISTS,
+ /**
+ * The method call for a create operation failed because multiple concepts already exists.
+ */
+ MULTIPLE_CONCEPTS_EXIST,
+ /** The method call on a concept failed because the referenced concept does not exist. */
+ CONCEPT_DOES_NOT_EXIST,
+ /** The method call failed because no action was specified on the method call. */
+ NO_ACTION_SPECIFIED,
+ /**
+ * The method call failed because of a structural error, a missing reference, or other error on the model.
+ */
+ FAILED,
+ /**
+ * The method call failed for another reason such as the method call is not implemented yet on the concept on
+ * which it was called.
+ */
+ OTHER_ERROR;
+
+ /**
+ * Check if a result is OK.
+ *
+ * @param result the result
+ * @return true if the result is not OK
+ */
+ public static boolean isOk(final Result result) {
+ return result == Result.SUCCESS || result == Result.FINISHED;
+ }
+
+ /**
+ * Check if a result is not OK.
+ *
+ * @param result the result
+ * @return true if the result is not OK
+ */
+ public static boolean isNok(final Result result) {
+ return !isOk(result);
+ }
+ }
+
+ private Result result;
+ private List<String> messages = new ArrayList<>();
+
+ /**
+ * The Default Constructor creates a result for a successful operation with no messages.
+ */
+ public ApexApiResult() {
+ result = Result.SUCCESS;
+ }
+
+ /**
+ * This Constructor creates a result with the given result status with no messages.
+ *
+ * @param result the result status to use on this result
+ */
+ public ApexApiResult(final Result result) {
+ this.result = result;
+ }
+
+ /**
+ * This Constructor creates a result with the given result status and message.
+ *
+ * @param result the result status to use on this result
+ * @param message the message to return with the result
+ */
+ public ApexApiResult(final Result result, final String message) {
+ this.result = result;
+ addMessage(message);
+ }
+
+ /**
+ * This Constructor creates a result with the given result status and {@link Throwable} object such as an exception.
+ * The message and stack trace from the {@link Throwable} object are added to the message list of this message.
+ *
+ * @param result the result status to use on this result
+ * @param throwable the throwable object from which to add the message and stack trace
+ */
+ public ApexApiResult(final Result result, final Throwable throwable) {
+ this.result = result;
+ addThrowable(throwable);
+ }
+
+ /**
+ * This Constructor creates a result with the given result status, message, and {@link Throwable} object such as an
+ * exception. The message and stack trace from the {@link Throwable} object are added to the message list of this
+ * message.
+ *
+ * @param result the result status to use on this result
+ * @param message the message to return with the result
+ * @param throwable the throwable object from which to add the message and stack trace
+ */
+ public ApexApiResult(final Result result, final String message, final Throwable throwable) {
+ this.result = result;
+ addMessage(message);
+ addThrowable(throwable);
+ }
+
+ /**
+ * This message is a utility message that checks if the result of an operation on the API was OK.
+ *
+ * @return true, if the result indicates the API operation succeeded
+ */
+ public boolean isOk() {
+ return Result.isOk(result);
+ }
+
+ /**
+ * This message is a utility message that checks if the result of an operation on the API was not OK.
+ *
+ * @return true, if the result indicates the API operation did not succeed
+ */
+ public boolean isNok() {
+ return Result.isNok(result);
+ }
+
+ /**
+ * Gets the result status of an API operation.
+ *
+ * @return the result status
+ */
+ public Result getResult() {
+ return result;
+ }
+
+ /**
+ * Gets the list of messages returned by an API operation.
+ *
+ * @return the list of messages returned by an API operation
+ */
+ public List<String> getMessages() {
+ return messages;
+ }
+
+ /**
+ * Gets all the messages returned by an API operation as a single string.
+ *
+ * @return the messages returned by an API operation as a single string
+ */
+ public String getMessage() {
+ final StringBuilder builder = new StringBuilder();
+ for (final String message : messages) {
+ builder.append(message);
+ builder.append('\n');
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Adds a message from an API operation to the bottom of the list of messages to be returned.
+ *
+ * @param message the message from an API operation to add to the bottom of the list of messages to be returned
+ */
+ public void addMessage(final String message) {
+ if (message != null && message.trim().length() > 0) {
+ messages.add(message);
+ }
+ }
+
+ /**
+ * Adds the message and stack trace from a {@link Throwable} object such as an exception from an API operation to
+ * the bottom of the list of messages to be returned.
+ *
+ * @param throwable the {@link Throwable} object such as an exception from an API operation from which the message
+ * and stack trace are to be extracted and placed at the bottom of the list of messages to be returned
+ */
+ public void addThrowable(final Throwable throwable) {
+ final StringWriter throwableStringWriter = new StringWriter();
+ final PrintWriter throwablePrintWriter = new PrintWriter(throwableStringWriter);
+ throwable.printStackTrace(throwablePrintWriter);
+ messages.add(throwable.getMessage());
+ messages.add(throwableStringWriter.toString());
+ }
+
+ /**
+ * Gets a representation of the {@link ApexApiResult} instance as a JSON string.
+ *
+ * @return the result instance JSON string
+ */
+ public String toJson() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("{\n");
+
+ builder.append("\"result\": \"");
+ builder.append(result.toString());
+ builder.append("\",\n");
+
+ builder.append("\"messages\": [");
+ boolean first = true;
+ for (final String message : messages) {
+ if (first) {
+ builder.append("\n\"");
+ first = false;
+ } else {
+ builder.append(",\n\"");
+ }
+ builder.append(message.replace("\"", "\\\\\""));
+ builder.append("\"");
+ }
+ builder.append("]\n");
+
+ builder.append("}\n");
+
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("result: ");
+ builder.append(result);
+ builder.append('\n');
+ builder.append(getMessage());
+ return builder.toString();
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexEditorApi.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexEditorApi.java
new file mode 100644
index 000000000..8974d1fa8
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexEditorApi.java
@@ -0,0 +1,905 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021-2022 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi;
+
+/**
+ * The Interface ApexEditorAPI is used to manipulate Apex models.
+ */
+public interface ApexEditorApi {
+ /*
+ * Model API Methods
+ */
+
+ /**
+ * Create model.
+ *
+ * @param name name of the model
+ * @param version version of the model, set to null to use the default version
+ * @param uuid model UUID, set to null to generate a UUID
+ * @param description model description, set to null to generate a description
+ * @return result of the operation
+ */
+ ApexApiResult createModel(final String name, final String version, final String uuid, final String description);
+
+ /**
+ * Update model.
+ *
+ * @param name name of the model
+ * @param version version of the model, set to null to update the latest version
+ * @param uuid key information UUID, set to null to not update
+ * @param description policy description, set to null to not update
+ * @return result of the operation
+ */
+ ApexApiResult updateModel(final String name, final String version, final String uuid, final String description);
+
+ /**
+ * Get the key of an Apex model.
+ *
+ * @return the result of the operation
+ */
+ ApexApiResult getModelKey();
+
+ /**
+ * List an Apex model.
+ *
+ * @return the result of the operation
+ */
+ ApexApiResult listModel();
+
+ /**
+ * Delete an Apex model, clear all the concepts in the model.
+ *
+ * @return the result of the operation
+ */
+ ApexApiResult deleteModel();
+
+ /*
+ * Key Information API Methods
+ */
+
+ /**
+ * Create key information.
+ *
+ * @param name name of the concept for the key information
+ * @param version version of the concept for the key information, set to null to use the default
+ * version
+ * @param uuid key information UUID, set to null to generate a UUID
+ * @param description key information description, set to null to generate a description
+ * @return result of the operation
+ */
+ ApexApiResult createKeyInformation(final String name, final String version, final String uuid,
+ final String description);
+
+ /**
+ * Update key information.
+ *
+ * @param name name of the concept for the key information
+ * @param version version of the concept for the key information, set to null to update the
+ * latest version
+ * @param uuid key information UUID, set to null to not update
+ * @param description key information description, set to null to not update
+ * @return result of the operation
+ */
+ ApexApiResult updateKeyInformation(final String name, final String version, final String uuid,
+ final String description);
+
+ /**
+ * List key information.
+ *
+ * @param name name of the concept for the key information, set to null to list all
+ * @param version starting version of the concept for the key information, set to null to list
+ * all versions
+ * @return result of the operation
+ */
+ ApexApiResult listKeyInformation(final String name, final String version);
+
+ /**
+ * Delete key information.
+ *
+ * @param name name of the concept for the key information
+ * @param version version of the concept for the key information, set to null to delete all
+ * versions
+ * @return result of the operation
+ */
+ ApexApiResult deleteKeyInformation(final String name, final String version);
+
+ /**
+ * Validate key information.
+ *
+ * @param name name of the concept for the key information
+ * @param version version of the concept for the key information, set to null to validate all
+ * versions
+ * @return result of the operation
+ */
+ ApexApiResult validateKeyInformation(final String name, final String version);
+
+ /*
+ * Context Schema API Methods
+ */
+
+ /**
+ * Create a context schema.
+ *
+ * @param name name of the context schema
+ * @param version version of the context schema, set to null to use the default version
+ * @param schemaFlavour a final String identifying the flavour of this context schema
+ * @param schemaDefinition a final String containing the definition of this context schema
+ * @param uuid context schema UUID, set to null to generate a UUID
+ * @param description context schema description, set to null to generate a description
+ * @return result of the operation
+ */
+ ApexApiResult createContextSchema(final String name, final String version, final String schemaFlavour,
+ final String schemaDefinition, final String uuid, final String description);
+
+ /**
+ * Update a context schema.
+ *
+ * @param name name of the context schema
+ * @param version version of the context schema, set to null to update the latest version
+ * @param schemaFlavour a final String identifying the flavour of this context schema
+ * @param schemaDefinition a final String containing the definition of this context schema
+ * @param uuid context schema UUID, set to null to not update
+ * @param description context schema description, set to null to not update
+ * @return result of the operation
+ */
+ ApexApiResult updateContextSchema(final String name, final String version, final String schemaFlavour,
+ final String schemaDefinition, final String uuid, final String description);
+
+ /**
+ * List context schemas.
+ *
+ * @param name name of the context schema, set to null to list all
+ * @param version starting version of the context schema, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult listContextSchemas(final String name, final String version);
+
+ /**
+ * Delete a context schema.
+ *
+ * @param name name of the context schema
+ * @param version version of the context schema, set to null to delete all versions
+ * @return result of the operation
+ */
+ ApexApiResult deleteContextSchema(final String name, final String version);
+
+ /**
+ * Validate context schemas.
+ *
+ * @param name name of the context schema, set to null to list all
+ * @param version starting version of the context schema, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult validateContextSchemas(final String name, final String version);
+
+ /*
+ * Event API Methods
+ */
+
+ /**
+ * Create an event.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to use the default version
+ * @param nameSpace of the event, set to null to use the default value
+ * @param source of the event, set to null to use the default value
+ * @param target of the event, set to null to use the default value
+ * @param uuid event UUID, set to null to generate a UUID
+ * @param description event description, set to null to generate a description
+ * @param toscaPolicyState specifies TOSCA policy processing status
+ * @return result of the operation
+ */
+ ApexApiResult createEvent(final String name, final String version, final String nameSpace, final String source,
+ final String target, final String uuid, final String description, final String toscaPolicyState);
+
+ /**
+ * Update an event.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to use the latest version
+ * @param nameSpace of the event, set to null to not update
+ * @param source of the event, set to null to not update
+ * @param target of the event, set to null to not update
+ * @param uuid event UUID, set to null to not update
+ * @param description event description, set to null to not update
+ * @param toscaPolicyState specifies TOSCA policy processing status
+ * @return result of the operation
+ */
+ ApexApiResult updateEvent(final String name, final String version, final String nameSpace, final String source,
+ final String target, final String uuid, final String description, final String toscaPolicyState);
+
+ /**
+ * List events.
+ *
+ * @param name name of the event, set to null to list all
+ * @param version starting version of the event, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult listEvent(final String name, final String version);
+
+ /**
+ * Delete an event.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to delete all versions
+ * @return result of the operation
+ */
+ ApexApiResult deleteEvent(final String name, final String version);
+
+ /**
+ * Validate events.
+ *
+ * @param name name of the event, set to null to list all
+ * @param version starting version of the event, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult validateEvent(final String name, final String version);
+
+ /**
+ * Create an event parameter.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to use the latest version
+ * @param parName of the parameter
+ * @param contextSchemaName name of the parameter context schema
+ * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+ * latest version
+ * @param optional true if the event parameter is optional, false otherwise
+ * @return result of the operation
+ */
+ ApexApiResult createEventPar(final String name, final String version, final String parName,
+ final String contextSchemaName, final String contextSchemaVersion, boolean optional);
+
+ /**
+ * List event parameters.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to list latest version
+ * @param parName name of the parameter, set to null to list all parameters of the event
+ * @return result of the operation
+ */
+ ApexApiResult listEventPar(final String name, final String version, final String parName);
+
+ /**
+ * Delete an event parameter.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to use the latest version
+ * @param parName of the parameter, set to null to delete all parameters
+ * @return result of the operation
+ */
+ ApexApiResult deleteEventPar(final String name, final String version, final String parName);
+
+ /*
+ * Context Album API Methods
+ */
+
+ /**
+ * Create a context album.
+ *
+ * @param name name of the context album
+ * @param version version of the context album, set to null to use the default version
+ * @param scope of the context album
+ * @param writable "true" or "t" if the context album is writable, set to null or any other
+ * value for a read-only album
+ * @param contextSchemaName name of the parameter context schema
+ * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+ * latest version
+ * @param uuid context album UUID, set to null to generate a UUID
+ * @param description context album description, set to null to generate a description
+ * @return result of the operation
+ */
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ ApexApiResult createContextAlbum(final String name, final String version, final String scope, final String writable,
+ final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+ final String description);
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * Update a context album.
+ *
+ * @param name name of the context album
+ * @param version version of the context album, set to null to use the default version
+ * @param scope of the context album
+ * @param writable "true" or "t" if the context album is writable, set to null or any other
+ * value for a read-only album
+ * @param contextSchemaName name of the parameter context schema
+ * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+ * latest version
+ * @param uuid context album UUID, set to null to generate a UUID
+ * @param description context album description, set to null to generate a description
+ * @return result of the operation
+ */
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ ApexApiResult updateContextAlbum(final String name, final String version, final String scope, final String writable,
+ final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+ final String description);
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * List context albums.
+ *
+ * @param name name of the context album, set to null to list all
+ * @param version starting version of the context album, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult listContextAlbum(final String name, final String version);
+
+ /**
+ * Delete a context album.
+ *
+ * @param name name of the context album
+ * @param version version of the context album, set to null to delete versions
+ * @return result of the operation
+ */
+ ApexApiResult deleteContextAlbum(final String name, final String version);
+
+ /**
+ * Validate context albums.
+ *
+ * @param name name of the context album, set to null to list all
+ * @param version starting version of the context album, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult validateContextAlbum(final String name, final String version);
+
+ /*
+ * Task API Methods
+ */
+
+ /**
+ * Create a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the default version
+ * @param uuid task UUID, set to null to generate a UUID
+ * @param description task description, set to null to generate a description
+ * @return result of the operation
+ */
+ ApexApiResult createTask(final String name, final String version, final String uuid, final String description);
+
+ /**
+ * Update a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param uuid task UUID, set to null to not update
+ * @param description task description, set to null to not update
+ * @return result of the operation
+ */
+ ApexApiResult updateTask(final String name, final String version, final String uuid, final String description);
+
+ /**
+ * List tasks.
+ *
+ * @param name name of the task, set to null to list all
+ * @param version starting version of the task, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult listTask(final String name, final String version);
+
+ /**
+ * Delete a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult deleteTask(final String name, final String version);
+
+ /**
+ * Validate tasks.
+ *
+ * @param name name of the task, set to null to list all
+ * @param version starting version of the task, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult validateTask(final String name, final String version);
+
+ /**
+ * Create logic for a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param logicFlavour the task logic flavour for the task, set to null to use the default task
+ * logic flavour
+ * @param logic the source code for the logic of the task
+ * @return result of the operation
+ */
+ ApexApiResult createTaskLogic(final String name, final String version, final String logicFlavour,
+ final String logic);
+
+ /**
+ * Update logic for a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param logicFlavour the task logic flavour for the task, set to null to not update
+ * @param logic the source code for the logic of the task, set to null to not update
+ * @return result of the operation
+ */
+ ApexApiResult updateTaskLogic(final String name, final String version, final String logicFlavour,
+ final String logic);
+
+ /**
+ * List task logic.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to list the latest version
+ * @return result of the operation
+ */
+ ApexApiResult listTaskLogic(final String name, final String version);
+
+ /**
+ * Delete logic for a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult deleteTaskLogic(final String name, final String version);
+
+ /**
+ * Create a task field.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param fieldName of the input field
+ * @param contextSchemaName name of the input field context schema
+ * @param contextSchemaVersion version of the input field context schema, set to null to use the
+ * latest version
+ * @param optional true if the task field is optional, false otherwise
+ * @return result of the operation
+ */
+ ApexApiResult createTaskField(final String name, final String version, final String fieldName,
+ final String contextSchemaName, final String contextSchemaVersion, boolean optional);
+
+ /**
+ * Handle a task field.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param fieldName field name of the input field, set to null to list all input fields of the
+ * task
+ * @return result of the operation
+ */
+ ApexApiResult handleTaskField(final String name, final String version, final String fieldName);
+
+ /**
+ * Create a task parameter.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param parName of the parameter
+ * @param defaultValue of the parameter
+ * @return result of the operation
+ */
+ ApexApiResult createTaskParameter(final String name, final String version, final String parName,
+ final String defaultValue);
+
+ /**
+ * List task parameters.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param parName name of the parameter, set to null to list all parameters of the task
+ * @return result of the operation
+ */
+ ApexApiResult listTaskParameter(final String name, final String version, final String parName);
+
+ /**
+ * Delete a task parameter.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param parName of the parameter, set to null to delete all task parameters
+ * @return result of the operation
+ */
+ ApexApiResult deleteTaskParameter(final String name, final String version, final String parName);
+
+ /**
+ * Create a task context album reference.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param contextAlbumName name of the context album for the context album reference
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult createTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion);
+
+ /**
+ * List task context album references.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param contextAlbumName name of the context album for the context album reference, set to
+ * null to list all task context album references
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult listTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion);
+
+ /**
+ * Delete a task context album reference.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param contextAlbumName name of the context album for the context album reference, set to
+ * null to delete all task context album references
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult deleteTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion);
+
+ /*
+ * Policy API Methods
+ */
+
+ /**
+ * Create a policy.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the default version
+ * @param template template used to create the policy, set to null to use the default template
+ * @param firstState the first state of the policy
+ * @param uuid policy UUID, set to null to generate a UUID
+ * @param description policy description, set to null to generate a description
+ * @return result of the operation
+ */
+ ApexApiResult createPolicy(final String name, final String version, final String template, final String firstState,
+ final String uuid, final String description);
+
+ /**
+ * Update a policy.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param template template used to create the policy, set to null to not update
+ * @param firstState the first state of the policy
+ * @param uuid policy UUID, set to null to not update
+ * @param description policy description, set to null to not update
+ * @return result of the operation
+ */
+ ApexApiResult updatePolicy(final String name, final String version, final String template, final String firstState,
+ final String uuid, final String description);
+
+ /**
+ * List policies.
+ *
+ * @param name name of the policy, set to null to list all
+ * @param version starting version of the policy, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult listPolicy(final String name, final String version);
+
+ /**
+ * Delete a policy.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult deletePolicy(final String name, final String version);
+
+ /**
+ * Validate policies.
+ *
+ * @param name name of the policy, set to null to list all
+ * @param version starting version of the policy, set to null to list all versions
+ * @return result of the operation
+ */
+ ApexApiResult validatePolicy(final String name, final String version);
+
+ /**
+ * Create a policy state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param triggerName name of the trigger event for this state
+ * @param triggerVersion version of the trigger event for this state, set to null to use the
+ * latest version
+ * @param defaultTaskName the default task name
+ * @param defaltTaskVersion the default task version, set to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult createPolicyState(final String name, final String version, final String stateName,
+ final String triggerName, final String triggerVersion, final String defaultTaskName,
+ final String defaltTaskVersion);
+
+ /**
+ * Update a policy state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param triggerName name of the trigger event for this state, set to null to not update
+ * @param triggerVersion version of the trigger event for this state, set to use latest version
+ * of trigger event
+ * @param defaultTaskName the default task name, set to null to not update
+ * @param defaltTaskVersion the default task version, set to use latest version of default task
+ * @return result of the operation
+ */
+ ApexApiResult updatePolicyState(final String name, final String version, final String stateName,
+ final String triggerName, final String triggerVersion, final String defaultTaskName,
+ final String defaltTaskVersion);
+
+ /**
+ * List policy states.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state, set to null to list all states of the policy
+ * @return result of the operation
+ */
+ ApexApiResult listPolicyState(final String name, final String version, final String stateName);
+
+ /**
+ * Delete a policy state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state, set to null to delete all states
+ * @return result of the operation
+ */
+ ApexApiResult deletePolicyState(final String name, final String version, final String stateName);
+
+ /**
+ * Create task selection logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param logicFlavour the task selection logic flavour for the state, set to null to use the
+ * default task logic flavour
+ * @param logic the source code for the logic of the state
+ * @return result of the operation
+ */
+ ApexApiResult createPolicyStateTaskSelectionLogic(final String name, final String version, final String stateName,
+ final String logicFlavour, final String logic);
+
+ /**
+ * Update task selection logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param logicFlavour the task selection logic flavour for the state, set to null to not update
+ * @param logic the source code for the logic of the state, set to null to not update
+ * @return result of the operation
+ */
+ ApexApiResult updatePolicyStateTaskSelectionLogic(final String name, final String version, final String stateName,
+ final String logicFlavour, final String logic);
+
+ /**
+ * List task selection logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @return result of the operation
+ */
+ ApexApiResult listPolicyStateTaskSelectionLogic(final String name, final String version, final String stateName);
+
+ /**
+ * Delete task selection logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @return result of the operation
+ */
+ ApexApiResult deletePolicyStateTaskSelectionLogic(final String name, final String version, final String stateName);
+
+ /**
+ * Create a policy state output.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param outputName of the state output
+ * @param eventName name of the output event for this state output
+ * @param eventVersion version of the output event for this state output, set to null to use the
+ * latest version
+ * @param nextState for this state to transition to, set to null if this is the last state that
+ * the policy transitions to on this branch
+ * @return result of the operation
+ */
+ ApexApiResult createPolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName, final String eventName, final String eventVersion, final String nextState);
+
+ /**
+ * List policy state outputs.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param outputName of the state output, set to null to list all outputs of the state
+ * @return result of the operation
+ */
+ ApexApiResult listPolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName);
+
+ /**
+ * Delete a policy state output.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param outputName of the state output, set to null to delete all state outputs
+ * @return result of the operation
+ */
+ ApexApiResult deletePolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName);
+
+ /**
+ * Create policy finalizer logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param finalizerLogicName name of the state finalizer logic
+ * @param logicFlavour the policy finalizer logic flavour for the state, set to null to use the
+ * default task logic flavour
+ * @param logic the source code for the logic of the state
+ * @return result of the operation
+ */
+ ApexApiResult createPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+ final String finalizerLogicName, final String logicFlavour, final String logic);
+
+ /**
+ * Update policy finalizer logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param finalizerLogicName name of the state finalizer logic
+ * @param logicFlavour the policy finalizer logic flavour for the state, set to null to not
+ * update
+ * @param logic the source code for the logic of the state, set to null to not update
+ * @return result of the operation
+ */
+ ApexApiResult updatePolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+ final String finalizerLogicName, final String logicFlavour, final String logic);
+
+ /**
+ * List policy finalizer logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param finalizerLogicName name of the state finalizer logic
+ * @return result of the operation
+ */
+ ApexApiResult listPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+ final String finalizerLogicName);
+
+ /**
+ * Delete policy finalizer logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param finalizerLogicName name of the state finalizer logic
+ * @return result of the operation
+ */
+ ApexApiResult deletePolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+ final String finalizerLogicName);
+
+ /**
+ * Create a policy state task reference.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param taskLocalName the task local name
+ * @param taskName name of the task
+ * @param taskVersion version of the task, set to null to use the latest version
+ * @param outputType Type of output for the task, must be DIRECT for direct output to a state
+ * output or LOGIC for output to state finalizer logic
+ * @param outputName the name of the state output or state state finalizer logic to handle the
+ * task output
+ * @return result of the operation
+ */
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ ApexApiResult createPolicyStateTaskRef(final String name, final String version, final String stateName,
+ final String taskLocalName, final String taskName, final String taskVersion, final String outputType,
+ final String outputName);
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * List policy state task references.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param taskName name of the task, set to null to list all task references
+ * @param taskVersion version of the task, set to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult listPolicyStateTaskRef(final String name, final String version, final String stateName,
+ final String taskName, final String taskVersion);
+
+ /**
+ * Delete a policy state task reference.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param taskName name of the task, set to null to delete all task references
+ * @param taskVersion version of the task, set to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult deletePolicyStateTaskRef(final String name, final String version, final String stateName,
+ final String taskName, final String taskVersion);
+
+ /**
+ * Create a policy state context album reference.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param contextAlbumName name of the context album for the context album reference
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult createPolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion);
+
+ /**
+ * List policy state context album references.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param contextAlbumName name of the context album for the context album reference, set to
+ * null to list all task context album references
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult listPolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion);
+
+ /**
+ * Delete a policy state context album reference.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the default version
+ * @param stateName of the state
+ * @param contextAlbumName name of the context album for the context album reference, set to
+ * null to delete all task context album references
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ ApexApiResult deletePolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion);
+} \ No newline at end of file
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexModel.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexModel.java
new file mode 100644
index 000000000..3c6e4c063
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexModel.java
@@ -0,0 +1,176 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.modelapi;
+
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+/**
+ * The Interface ApexModelAPI provides functional methods that allow Apex models to be managed.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface ApexModel extends ApexEditorApi {
+ /**
+ * Make a deep copy of the Model.
+ *
+ * @return the result of the operation
+ */
+ ApexModel getCopy();
+
+ /**
+ * Load an Apex model from a string.
+ *
+ * @param modelString the string with the model
+ * @return the result of the operation
+ */
+ ApexApiResult loadFromString(String modelString);
+
+ /**
+ * Load an Apex model from a file.
+ *
+ * @param fileName the file name of the file with the model
+ * @return the result of the operation
+ */
+ ApexApiResult loadFromFile(String fileName);
+
+ /**
+ * Save an Apex model to a file.
+ *
+ * @param fileName the file name
+ * @return the result of the operation
+ */
+ ApexApiResult saveToFile(String fileName);
+
+ /**
+ * Read an APEX model from a location identified by a URL.
+ *
+ * @param urlString the url string
+ * @return the result of the operation
+ */
+ ApexApiResult readFromUrl(String urlString);
+
+ /**
+ * Write an APEX model to a location identified by a URL.
+ *
+ * @param urlString the URL to read the model from
+ * @return the result of the operation
+ */
+ ApexApiResult writeToUrl(String urlString);
+
+ /**
+ * Analyse an Apex model that shows the concept usage references of a policy model.
+ *
+ * @return the result of the operation
+ */
+ ApexApiResult analyse();
+
+ /**
+ * Validate an Apex model, checking all concepts and references in the model.
+ *
+ * @return the result of the operation
+ */
+ ApexApiResult validate();
+
+ /**
+ * Compare to Apex models, returning the differences between the models.
+ *
+ * @param otherModelFileName the file name of the other model
+ * @param diffsOnly only returns differences between the model when set
+ * @param keysOnly only returns the keys that are different when set, when not set values are also returned
+ * @return the result of the operation
+ */
+ ApexApiResult compare(String otherModelFileName, boolean diffsOnly, boolean keysOnly);
+
+ /**
+ * Compare two Apex models, returning the differences between the models.
+ *
+ * @param otherModelString the other model as a string
+ * @param diffsOnly only returns differences between the model when set
+ * @param keysOnly only returns the keys that are different when set, when not set values are also returned
+ * @return the result of the operation
+ */
+ ApexApiResult compareWithString(String otherModelString, boolean diffsOnly, boolean keysOnly);
+
+ /**
+ * Split out a sub model from an Apex model that contains a given subset of the policies in the original model.
+ *
+ * @param targetModelName the file name of the target model in which to store the model split out from the original
+ * model
+ * @param splitOutPolicies the policies form the original model to include in the split out model, specified as a
+ * comma delimited list of policy names
+ * @return the result of the operation
+ */
+ ApexApiResult split(String targetModelName, String splitOutPolicies);
+
+ /**
+ * Split out a sub model from an Apex model that contains a given subset of the policies in the original model,
+ * return the split model in the result as a string.
+ *
+ * @param splitOutPolicies the policies form the original model to include in the split out model, specified as a
+ * comma delimited list of policy names
+ * @return the result of the operation
+ */
+ ApexApiResult split(String splitOutPolicies);
+
+ /**
+ * Merge two Apex models together.
+ *
+ * @param mergeInModelName the file name of the model to merge into the current model
+ * @param keepOriginal if this flag is set to true, if a concept exists in both models, the original model copy of
+ * that concept is kept, if the flag is set to false, then the copy of the concept from the mergeInModel
+ * overwrites the concept in the original model
+ * @return the result of the operation
+ */
+ ApexApiResult merge(String mergeInModelName, boolean keepOriginal);
+
+ /**
+ * Merge two Apex models together.
+ *
+ * @param otherModelString the model to merge as a string
+ * @param keepOriginal if this flag is set to true, if a concept exists in both models, the original model copy of
+ * that concept is kept, if the flag is set to false, then the copy of the concept from the mergeInModel
+ * overwrites the concept in the original model
+ * @return the result of the operation
+ */
+ ApexApiResult mergeWithString(String otherModelString, boolean keepOriginal);
+
+ /**
+ * Get the raw policy model being used by this model.
+ *
+ * @return the policy model
+ */
+ AxPolicyModel getPolicyModel();
+
+ /**
+ * Set the raw policy model being used by this model.
+ *
+ * @param policyModel the policy model
+ */
+ void setPolicyModel(AxPolicyModel policyModel);
+
+ /**
+ * Builds the raw policy model being used by this model.
+ *
+ * @return the policy model
+ */
+ AxPolicyModel build();
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexModelFactory.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexModelFactory.java
new file mode 100644
index 000000000..908f562d2
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/ApexModelFactory.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.modelapi;
+
+import java.util.Properties;
+import org.onap.policy.apex.model.modelapi.impl.ApexModelImpl;
+
+/**
+ * A factory for creating ApexModel objects using the Apex Model implementation.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexModelFactory {
+
+ /**
+ * Creates a new ApexModel object from its implementation.
+ *
+ * @param apexProperties default values and other configuration information for the apex model
+ * @return the apex model
+ */
+ public ApexModel createApexModel(final Properties apexProperties) {
+ return new ApexModelImpl(setDefaultPropertyValues(apexProperties));
+ }
+
+ /**
+ * Sets default property values for Apex properties that must be set for the Apex model
+ * implementation if those properties are not already set.
+ *
+ * @param apexPropertiesIn the default property values
+ * @return the properties
+ */
+ private Properties setDefaultPropertyValues(final Properties apexPropertiesIn) {
+ Properties apexProperties = apexPropertiesIn;
+
+ if (apexProperties == null) {
+ apexProperties = new Properties();
+ }
+
+ if (apexProperties.getProperty("DEFAULT_CONCEPT_VERSION") == null) {
+ apexProperties.setProperty("DEFAULT_CONCEPT_VERSION", "0.0.1");
+ }
+ if (apexProperties.getProperty("DEFAULT_EVENT_NAMESPACE") == null) {
+ apexProperties.setProperty("DEFAULT_EVENT_NAMESPACE", "org.onap.policy.apex");
+ }
+ if (apexProperties.getProperty("DEFAULT_EVENT_SOURCE") == null) {
+ apexProperties.setProperty("DEFAULT_EVENT_SOURCE", "source");
+ }
+ if (apexProperties.getProperty("DEFAULT_EVENT_TARGET") == null) {
+ apexProperties.setProperty("DEFAULT_EVENT_TARGET", "target");
+ }
+ if (apexProperties.getProperty("DEFAULT_POLICY_TEMPLATE") == null) {
+ apexProperties.setProperty("DEFAULT_POLICY_TEMPLATE", "FREEFORM");
+ }
+
+ return apexProperties;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ApexModelImpl.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ApexModelImpl.java
new file mode 100644
index 000000000..54b94d0e7
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ApexModelImpl.java
@@ -0,0 +1,866 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi.impl;
+
+import java.util.Properties;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexApiResult.Result;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class is an implementation of a facade on an Apex model for editors of Apex models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ApexModelImpl implements ApexModel {
+
+ public static final String FIELDS_DEPRECATED_WARN_MSG =
+ "inputFields and outputFields are deprecated from Task definition and will be removed. "
+ + "Instead, inputEvent and outputEvents are automatically populated to Tasks based on State definition";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApexModelImpl.class);
+
+ // The policy model being acted upon
+ @Getter
+ @Setter
+ private AxPolicyModel policyModel = new AxPolicyModel();
+
+ // @formatter:off
+ private ModelFacade modelFacade;
+ private KeyInformationFacade keyInformationFacade;
+ private ContextSchemaFacade contextSchemaFacade;
+ private EventFacade eventFacade;
+ private ContextAlbumFacade contextAlbumFacade;
+ private TaskFacade taskFacade;
+ private PolicyFacade policyFacade;
+ private ModelHandlerFacade modelHandlerFacade;
+ // @formatter:on
+
+ private Properties apexProperties;
+
+ /**
+ * Create an implementation of the Apex editor and model APIs.
+ *
+ * @param apexProperties The properties to use for the model
+ */
+ public ApexModelImpl(final Properties apexProperties) {
+ this.apexProperties = apexProperties;
+
+ // @formatter:off
+ this.modelFacade = new ModelFacade(this, apexProperties);
+ this.keyInformationFacade = new KeyInformationFacade(this, apexProperties);
+ this.contextSchemaFacade = new ContextSchemaFacade(this, apexProperties);
+ this.eventFacade = new EventFacade(this, apexProperties);
+ this.contextAlbumFacade = new ContextAlbumFacade(this, apexProperties);
+ this.taskFacade = new TaskFacade(this, apexProperties);
+ this.policyFacade = new PolicyFacade(this, apexProperties);
+ this.modelHandlerFacade = new ModelHandlerFacade(this, apexProperties);
+ // @formatter:on
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexModel getCopy() {
+ ApexModelImpl ret = new ApexModelImpl();
+ // @formatter:off
+ ret.policyModel = new AxPolicyModel(policyModel);
+ ret.apexProperties = this.apexProperties;
+ ret.modelFacade = new ModelFacade(ret, this.apexProperties);
+ ret.keyInformationFacade = new KeyInformationFacade(ret, this.apexProperties);
+ ret.contextSchemaFacade = new ContextSchemaFacade(ret, this.apexProperties);
+ ret.eventFacade = new EventFacade(ret, this.apexProperties);
+ ret.contextAlbumFacade = new ContextAlbumFacade(ret, this.apexProperties);
+ ret.taskFacade = new TaskFacade(ret, this.apexProperties);
+ ret.policyFacade = new PolicyFacade(ret, this.apexProperties);
+ ret.modelHandlerFacade = new ModelHandlerFacade(ret, this.apexProperties);
+ // @formatter:on
+
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createModel(final String name, final String version, final String uuid,
+ final String description) {
+ return modelFacade.createModel(name, version, uuid, description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updateModel(final String name, final String version, final String uuid,
+ final String description) {
+ return modelFacade.updateModel(name, version, uuid, description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult getModelKey() {
+ return modelFacade.getModelKey();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listModel() {
+ return modelFacade.listModel();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteModel() {
+ return modelFacade.deleteModel();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createKeyInformation(final String name, final String version, final String uuid,
+ final String description) {
+ return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updateKeyInformation(final String name, final String version, final String uuid,
+ final String description) {
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listKeyInformation(final String name, final String version) {
+ return keyInformationFacade.listKeyInformation(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteKeyInformation(final String name, final String version) {
+ return keyInformationFacade.deleteKeyInformation(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult validateKeyInformation(final String name, final String version) {
+ return keyInformationFacade.validateKeyInformation(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createContextSchema(final String name, final String version, final String schemaFlavour,
+ final String schemaDefinition, final String uuid, final String description) {
+ return contextSchemaFacade.createContextSchema(name, version, schemaFlavour, schemaDefinition, uuid,
+ description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updateContextSchema(final String name, final String version, final String schemaFlavour,
+ final String schemaDefinition, final String uuid, final String description) {
+ return contextSchemaFacade.updateContextSchema(name, version, schemaFlavour, schemaDefinition, uuid,
+ description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listContextSchemas(final String name, final String version) {
+ return contextSchemaFacade.listContextSchemas(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteContextSchema(final String name, final String version) {
+ return contextSchemaFacade.deleteContextSchema(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult validateContextSchemas(final String name, final String version) {
+ return contextSchemaFacade.validateContextSchemas(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createEvent(final String name, final String version, final String nameSpace,
+ final String source, final String target, final String uuid, final String description,
+ final String toscaPolicyState) {
+ return eventFacade.createEvent(name, version, nameSpace, source, target, uuid, description, toscaPolicyState);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updateEvent(final String name, final String version, final String nameSpace,
+ final String source, final String target, final String uuid, final String description,
+ final String toscaPolicyState) {
+ return eventFacade.updateEvent(name, version, nameSpace, source, target, uuid, description, toscaPolicyState);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listEvent(final String name, final String version) {
+ return eventFacade.listEvent(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteEvent(final String name, final String version) {
+ return eventFacade.deleteEvent(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult validateEvent(final String name, final String version) {
+ return eventFacade.validateEvent(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createEventPar(final String name, final String version, final String parName,
+ final String contextSchemaName, final String contextSchemaVersion, final boolean optional) {
+ return eventFacade.createEventPar(name, version, parName, contextSchemaName, contextSchemaVersion, optional);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listEventPar(final String name, final String version, final String parName) {
+ return eventFacade.listEventPar(name, version, parName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteEventPar(final String name, final String version, final String parName) {
+ return eventFacade.deleteEventPar(name, version, parName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ public ApexApiResult createContextAlbum(final String name, final String version, final String scope,
+ final String writable, final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+ final String description) {
+ return contextAlbumFacade.createContextAlbum(ContextAlbum.builder().name(name).version(version)
+ .scope(scope).writable(writable).contextSchemaName(contextSchemaName)
+ .contextSchemaVersion(contextSchemaVersion).uuid(uuid).description(description).build());
+ }
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * {@inheritDoc}.
+ */
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ @Override
+ public ApexApiResult updateContextAlbum(final String name, final String version, final String scope,
+ final String writable, final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+ final String description) {
+ return contextAlbumFacade.updateContextAlbum(ContextAlbum.builder().name(name).version(version)
+ .scope(scope).writable(writable).contextSchemaName(contextSchemaName)
+ .contextSchemaVersion(contextSchemaVersion).uuid(uuid).description(description).build());
+ }
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listContextAlbum(final String name, final String version) {
+ return contextAlbumFacade.listContextAlbum(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteContextAlbum(final String name, final String version) {
+ return contextAlbumFacade.deleteContextAlbum(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult validateContextAlbum(final String name, final String version) {
+ return contextAlbumFacade.validateContextAlbum(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createTask(final String name, final String version, final String uuid,
+ final String description) {
+ return taskFacade.createTask(name, version, uuid, description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updateTask(final String name, final String version, final String uuid,
+ final String description) {
+ return taskFacade.updateTask(name, version, uuid, description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listTask(final String name, final String version) {
+ return taskFacade.listTask(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteTask(final String name, final String version) {
+ return taskFacade.deleteTask(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult validateTask(final String name, final String version) {
+ return taskFacade.validateTask(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createTaskLogic(final String name, final String version, final String logicFlavour,
+ final String logic) {
+ return taskFacade.createTaskLogic(name, version, logicFlavour, logic);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updateTaskLogic(final String name, final String version, final String logicFlavour,
+ final String logic) {
+ return taskFacade.updateTaskLogic(name, version, logicFlavour, logic);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listTaskLogic(final String name, final String version) {
+ return taskFacade.listTaskLogic(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteTaskLogic(final String name, final String version) {
+ return taskFacade.deleteTaskLogic(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createTaskField(final String name, final String version, final String fieldName,
+ final String dataTypeName, final String dataTypeVersion, final boolean optional) {
+ LOGGER.warn(FIELDS_DEPRECATED_WARN_MSG);
+ return new ApexApiResult(Result.SUCCESS, FIELDS_DEPRECATED_WARN_MSG);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult handleTaskField(final String name, final String version, final String fieldName) {
+ LOGGER.warn(FIELDS_DEPRECATED_WARN_MSG);
+ return new ApexApiResult(Result.SUCCESS, FIELDS_DEPRECATED_WARN_MSG);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createTaskParameter(final String name, final String version, final String parName,
+ final String defaultValue) {
+ return taskFacade.createTaskParameter(name, version, parName, defaultValue);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listTaskParameter(final String name, final String version, final String parName) {
+ return taskFacade.listTaskParameter(name, version, parName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteTaskParameter(final String name, final String version, final String parName) {
+ return taskFacade.deleteTaskParameter(name, version, parName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion) {
+ return taskFacade.createTaskContextRef(name, version, contextAlbumName, contextAlbumVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion) {
+ return taskFacade.listTaskContextRef(name, version, contextAlbumName, contextAlbumVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deleteTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion) {
+ return taskFacade.deleteTaskContextRef(name, version, contextAlbumName, contextAlbumVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createPolicy(final String name, final String version, final String template,
+ final String firstState, final String uuid, final String description) {
+ return policyFacade.createPolicy(name, version, template, firstState, uuid, description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updatePolicy(final String name, final String version, final String template,
+ final String firstState, final String uuid, final String description) {
+ return policyFacade.updatePolicy(name, version, template, firstState, uuid, description);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listPolicy(final String name, final String version) {
+ return policyFacade.listPolicy(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deletePolicy(final String name, final String version) {
+ return policyFacade.deletePolicy(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult validatePolicy(final String name, final String version) {
+ return policyFacade.validatePolicy(name, version);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createPolicyState(final String name, final String version, final String stateName,
+ final String triggerName, final String triggerVersion, final String defaultTaskName,
+ final String defaltTaskVersion) {
+ return policyFacade.createPolicyState(name, version, stateName, triggerName, triggerVersion, defaultTaskName,
+ defaltTaskVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updatePolicyState(final String name, final String version, final String stateName,
+ final String triggerName, final String triggerVersion, final String defaultTaskName,
+ final String defaltTaskVersion) {
+ return policyFacade.updatePolicyState(name, version, stateName, triggerName, triggerVersion, defaultTaskName,
+ defaltTaskVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listPolicyState(final String name, final String version, final String stateName) {
+ return policyFacade.listPolicyState(name, version, stateName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deletePolicyState(final String name, final String version, final String stateName) {
+ return policyFacade.deletePolicyState(name, version, stateName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createPolicyStateTaskSelectionLogic(final String name, final String version,
+ final String stateName, final String logicFlavour, final String logic) {
+ return policyFacade.createPolicyStateTaskSelectionLogic(name, version, stateName, logicFlavour, logic);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updatePolicyStateTaskSelectionLogic(final String name, final String version,
+ final String stateName, final String logicFlavour, final String logic) {
+ return policyFacade.updatePolicyStateTaskSelectionLogic(name, version, stateName, logicFlavour, logic);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listPolicyStateTaskSelectionLogic(final String name, final String version,
+ final String stateName) {
+ return policyFacade.listPolicyStateTaskSelectionLogic(name, version, stateName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deletePolicyStateTaskSelectionLogic(final String name, final String version,
+ final String stateName) {
+ return policyFacade.deletePolicyStateTaskSelectionLogic(name, version, stateName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createPolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName, final String eventName, final String eventVersion, final String nextState) {
+ return policyFacade.createPolicyStateOutput(name, version, stateName, outputName, eventName, eventVersion,
+ nextState);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listPolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName) {
+ return policyFacade.listPolicyStateOutput(name, version, stateName, outputName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deletePolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName) {
+ return policyFacade.deletePolicyStateOutput(name, version, stateName, outputName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createPolicyStateFinalizerLogic(final String name, final String version,
+ final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
+ return policyFacade.createPolicyStateFinalizerLogic(name, version, stateName, finalizerLogicName, logicFlavour,
+ logic);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult updatePolicyStateFinalizerLogic(final String name, final String version,
+ final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
+ return policyFacade.updatePolicyStateFinalizerLogic(name, version, stateName, finalizerLogicName, logicFlavour,
+ logic);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+ final String finalizerLogicName) {
+ return policyFacade.listPolicyStateFinalizerLogic(name, version, stateName, finalizerLogicName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deletePolicyStateFinalizerLogic(final String name, final String version,
+ final String stateName, final String finalizerLogicName) {
+ return policyFacade.deletePolicyStateFinalizerLogic(name, version, stateName, finalizerLogicName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ public ApexApiResult createPolicyStateTaskRef(final String name, final String version, final String stateName,
+ final String taskLocalName, final String taskName, final String taskVersion, final String outputType,
+ final String outputName) {
+ return policyFacade.createPolicyStateTaskRef(CreatePolicyStateTaskRef.builder().name(name)
+ .version(version).stateName(stateName).taskLocalName(taskLocalName).taskName(taskName)
+ .taskVersion(taskVersion).outputType(outputType).outputName(outputName).build());
+ }
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listPolicyStateTaskRef(final String name, final String version, final String stateName,
+ final String taskName, final String taskVersion) {
+ return policyFacade.listPolicyStateTaskRef(name, version, stateName, taskName, taskVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deletePolicyStateTaskRef(final String name, final String version, final String stateName,
+ final String taskName, final String taskVersion) {
+ return policyFacade.deletePolicyStateTaskRef(name, version, stateName, taskName, taskVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult createPolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion) {
+ return policyFacade.createPolicyStateContextRef(name, version, stateName, contextAlbumName,
+ contextAlbumVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult listPolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion) {
+ return policyFacade.listPolicyStateContextRef(name, version, stateName, contextAlbumName, contextAlbumVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult deletePolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion) {
+ return policyFacade.deletePolicyStateContextRef(name, version, stateName, contextAlbumName,
+ contextAlbumVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult loadFromString(final String modelString) {
+ return modelHandlerFacade.loadFromString(modelString);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ // CHECKSTYLE:OFF: checkstyle:HiddenField
+ public ApexApiResult loadFromFile(final String fileName) {
+ return modelHandlerFacade.loadFromFile(fileName);
+ }
+ // CHECKSTYLE:ON: checkstyle:HiddenField
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult saveToFile(final String fileName) {
+ return modelHandlerFacade.saveToFile(fileName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult readFromUrl(final String urlString) {
+ return modelHandlerFacade.readFromUrl(urlString);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult writeToUrl(final String urlString) {
+ return modelHandlerFacade.writeToUrl(urlString);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult analyse() {
+ return modelHandlerFacade.analyse();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult validate() {
+ return modelHandlerFacade.validate();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult compare(final String otherModelFileName, final boolean diffsOnly, final boolean keysOnly) {
+ return modelHandlerFacade.compare(otherModelFileName, diffsOnly, keysOnly);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult compareWithString(final String otherModelString, final boolean diffsOnly,
+ final boolean keysOnly) {
+ return modelHandlerFacade.compareWithString(otherModelString, diffsOnly, keysOnly);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult split(final String targetModelFileName, final String splitOutPolicies) {
+ return modelHandlerFacade.split(targetModelFileName, splitOutPolicies);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult split(final String splitOutPolicies) {
+ return modelHandlerFacade.split(splitOutPolicies);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult merge(final String mergeInModelFileName, final boolean keepOriginal) {
+ return modelHandlerFacade.merge(mergeInModelFileName, keepOriginal);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public ApexApiResult mergeWithString(final String otherModelString, final boolean keepOriginal) {
+ return modelHandlerFacade.mergeWithString(otherModelString, keepOriginal);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxPolicyModel build() {
+ return policyModel;
+ }
+
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbum.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbum.java
new file mode 100644
index 000000000..5a42ed14e
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbum.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Samsung Electronics Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi.impl;
+
+import lombok.Builder;
+import lombok.Getter;
+
+@Getter
+@Builder
+public class ContextAlbum {
+ private String name;
+ private String version;
+ private String scope;
+ private String writable;
+ private String contextSchemaName;
+ private String contextSchemaVersion;
+ private String uuid;
+ private String description;
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbumFacade.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbumFacade.java
new file mode 100644
index 000000000..d29f32ea0
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbumFacade.java
@@ -0,0 +1,254 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+
+/**
+ * This class acts as a facade for operations towards a policy model for context album operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextAlbumFacade {
+ private static final String CONCEPT = "concept ";
+ private static final String CONCEPT_S = "concept(s) ";
+ private static final String DOES_NOT_EXIST = " does not exist";
+ private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+
+ // Apex model we're working towards
+ private final ApexModel apexModel;
+
+ // Properties to use for the model
+ private final Properties apexProperties;
+
+ // Facade classes for working towards the real Apex model
+ private final KeyInformationFacade keyInformationFacade;
+
+ /**
+ * Constructor that creates a context album facade for the Apex Model API.
+ *
+ * @param apexModel the apex model
+ * @param apexProperties Properties for the model
+ */
+ public ContextAlbumFacade(final ApexModel apexModel, final Properties apexProperties) {
+ this.apexModel = apexModel;
+ this.apexProperties = apexProperties;
+
+ keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties);
+ }
+
+ /**
+ * Create a context album.
+ *
+ * @param builder the builder for the context album parameters
+ * @return result of the operation
+ */
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ public ApexApiResult createContextAlbum(ContextAlbum builder) {
+ try {
+ final AxArtifactKey key = new AxArtifactKey();
+ key.setName(builder.getName());
+ if (builder.getVersion() != null) {
+ key.setVersion(builder.getVersion());
+ } else {
+ key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+ }
+
+ if (apexModel.getPolicyModel().getAlbums().getAlbumsMap().containsKey(key)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ CONCEPT + key.getId() + " already exists");
+ }
+
+ final AxContextSchema schema = apexModel.getPolicyModel().getSchemas().get(builder.getContextSchemaName(),
+ builder.getContextSchemaVersion());
+ if (schema == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, CONCEPT
+ + builder.getContextSchemaName() + ':' + builder.getContextSchemaVersion() + DOES_NOT_EXIST);
+ }
+
+ final AxContextAlbum contextAlbum = new AxContextAlbum(key);
+ contextAlbum.setScope(builder.getScope());
+ contextAlbum.setItemSchema(schema.getKey());
+
+ contextAlbum
+ .setWritable(builder.getWritable() != null && ("true".equalsIgnoreCase(builder.getWritable().trim())
+ || "t".equalsIgnoreCase(builder.getWritable().trim())));
+
+ apexModel.getPolicyModel().getAlbums().getAlbumsMap().put(key, contextAlbum);
+
+ if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+ return keyInformationFacade.updateKeyInformation(builder.getName(), builder.getVersion(),
+ builder.getUuid(), builder.getDescription());
+ } else {
+ return keyInformationFacade.createKeyInformation(builder.getName(), builder.getVersion(),
+ builder.getUuid(), builder.getDescription());
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * Update a context album.
+ *
+ * @param builder the builder for the context album parameters
+ * @return result of the operation
+ */
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ public ApexApiResult updateContextAlbum(ContextAlbum builder) {
+ try {
+ final AxContextAlbum contextAlbum =
+ apexModel.getPolicyModel().getAlbums().get(builder.getName(), builder.getVersion());
+ if (contextAlbum == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + builder.getName() + ':' + builder.getVersion() + DOES_NOT_EXIST);
+ }
+
+ if (builder.getScope() != null) {
+ contextAlbum.setScope(builder.getScope());
+ }
+
+ contextAlbum
+ .setWritable(builder.getWritable() != null && ("true".equalsIgnoreCase(builder.getWritable().trim())
+ || "t".equalsIgnoreCase(builder.getWritable().trim())));
+
+ if (builder.getContextSchemaName() != null) {
+ final AxContextSchema schema = apexModel.getPolicyModel().getSchemas()
+ .get(builder.getContextSchemaName(), builder.getContextSchemaVersion());
+ if (schema == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, CONCEPT
+ + builder.getContextSchemaName() + ':' + builder.getContextSchemaVersion() + DOES_NOT_EXIST);
+ }
+ contextAlbum.setItemSchema(schema.getKey());
+ }
+
+ return keyInformationFacade.updateKeyInformation(builder.getName(), builder.getVersion(), builder.getUuid(),
+ builder.getDescription());
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * List context albums.
+ *
+ * @param name name of the context album, set to null to list all
+ * @param version starting version of the context album, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult listContextAlbum(final String name, final String version) {
+ try {
+ final Set<AxContextAlbum> contextAlbumSet = apexModel.getPolicyModel().getAlbums().getAll(name, version);
+ if (name != null && contextAlbumSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxContextAlbum contextAlbum : contextAlbumSet) {
+ result.addMessage(
+ new ApexModelStringWriter<AxContextAlbum>(false).writeString(contextAlbum, AxContextAlbum.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a context album.
+ *
+ * @param name name of the context album
+ * @param version version of the context album, set to null to delete versions
+ * @return result of the operation
+ */
+ public ApexApiResult deleteContextAlbum(final String name, final String version) {
+ try {
+ if (version != null) {
+ final AxArtifactKey key = new AxArtifactKey(name, version);
+ if (apexModel.getPolicyModel().getAlbums().getAlbumsMap().remove(key) != null) {
+ return new ApexApiResult();
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + key.getId() + DOES_NOT_EXIST);
+ }
+ }
+
+ final Set<AxContextAlbum> contextAlbumSet = apexModel.getPolicyModel().getAlbums().getAll(name, version);
+ if (contextAlbumSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxContextAlbum contextAlbum : contextAlbumSet) {
+ result.addMessage(
+ new ApexModelStringWriter<AxContextAlbum>(false).writeString(contextAlbum, AxContextAlbum.class));
+ apexModel.getPolicyModel().getAlbums().getAlbumsMap().remove(contextAlbum.getKey());
+ keyInformationFacade.deleteKeyInformation(name, version);
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Validate context albums.
+ *
+ * @param name name of the context album, set to null to list all
+ * @param version starting version of the context album, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult validateContextAlbum(final String name, final String version) {
+ try {
+ final Set<AxContextAlbum> contextAlbumSet = apexModel.getPolicyModel().getAlbums().getAll(name, version);
+ if (contextAlbumSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxContextAlbum contextAlbum : contextAlbumSet) {
+ final AxValidationResult validationResult = contextAlbum.validate(new AxValidationResult());
+ result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(contextAlbum.getKey(),
+ AxArtifactKey.class));
+ result.addMessage(validationResult.toString());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextSchemaFacade.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextSchemaFacade.java
new file mode 100644
index 000000000..83bca5a01
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextSchemaFacade.java
@@ -0,0 +1,238 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,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.onap.policy.apex.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model for context schema operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextSchemaFacade {
+ private static final String CONCEPT = "concept ";
+ private static final String CONCEPT_S = "concept(s) ";
+ private static final String DOES_NOT_EXIST = " does not exist";
+ private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+ private static final String ALREADY_EXISTS = " already exists";
+
+ // Apex model we're working towards
+ private final ApexModel apexModel;
+
+ // Properties to use for the model
+ private final Properties apexProperties;
+
+ // Facade classes for working towards the real Apex model
+ private final KeyInformationFacade keyInformationFacade;
+
+ /**
+ * Constructor to create the context schema facade for the Model API.
+ *
+ * @param apexModel the apex model
+ * @param apexProperties Properties for the model
+ */
+ public ContextSchemaFacade(final ApexModel apexModel, final Properties apexProperties) {
+ this.apexModel = apexModel;
+ this.apexProperties = apexProperties;
+
+ keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties);
+ }
+
+ /**
+ * Create a context schema.
+ *
+ * @param name name of the context schema
+ * @param version version of the context schema, set to null to use the default version
+ * @param schemaFlavour a string identifying the flavour of this context schema
+ * @param schemaDefinition a string containing the definition of this context schema
+ * @param uuid context schema UUID, set to null to generate a UUID
+ * @param description context schema description, set to null to generate a description
+ * @return result of the operation
+ */
+ public ApexApiResult createContextSchema(final String name, final String version, final String schemaFlavour,
+ final String schemaDefinition, final String uuid, final String description) {
+ try {
+ Assertions.argumentNotNull(schemaFlavour, "schemaFlavour may not be null");
+
+ final AxArtifactKey key = new AxArtifactKey();
+ key.setName(name);
+ if (version != null) {
+ key.setVersion(version);
+ } else {
+ key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+ }
+
+ if (apexModel.getPolicyModel().getSchemas().getSchemasMap().containsKey(key)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, CONCEPT + key.getId() + ALREADY_EXISTS);
+ }
+
+ apexModel.getPolicyModel().getSchemas().getSchemasMap().put(key,
+ new AxContextSchema(key, schemaFlavour, schemaDefinition));
+
+ if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } else {
+ return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update a context schema.
+ *
+ * @param name name of the context schema
+ * @param version version of the context schema, set to null to update the latest version
+ * @param schemaFlavour a string identifying the flavour of this context schema
+ * @param schemaDefinition a string containing the definition of this context schema
+ * @param uuid context schema UUID, set to null to not update
+ * @param description context schema description, set to null to not update
+ * @return result of the operation
+ */
+ public ApexApiResult updateContextSchema(final String name, final String version, final String schemaFlavour,
+ final String schemaDefinition, final String uuid, final String description) {
+ try {
+ final AxContextSchema schema = apexModel.getPolicyModel().getSchemas().get(name, version);
+ if (schema == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ if (schemaFlavour != null) {
+ schema.setSchemaFlavour(schemaFlavour);
+ }
+
+ if (schemaDefinition != null) {
+ schema.setSchema(schemaDefinition);
+ }
+
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List context schemas.
+ *
+ * @param name name of the context schema, set to null to list all
+ * @param version starting version of the context schema, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult listContextSchemas(final String name, final String version) {
+ try {
+ final Set<AxContextSchema> schemaSet = apexModel.getPolicyModel().getSchemas().getAll(name, version);
+ if (name != null && schemaSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxContextSchema schema : schemaSet) {
+ result.addMessage(
+ new ApexModelStringWriter<AxContextSchema>(false).writeString(schema, AxContextSchema.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a context schema.
+ *
+ * @param name name of the context schema
+ * @param version version of the context schema, set to null to delete all versions
+ * @return result of the operation
+ */
+ public ApexApiResult deleteContextSchema(final String name, final String version) {
+ try {
+ if (version != null) {
+ final AxArtifactKey key = new AxArtifactKey(name, version);
+ final AxContextSchema removedSchema =
+ apexModel.getPolicyModel().getSchemas().getSchemasMap().remove(key);
+ if (removedSchema != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxContextSchema>(false).writeString(removedSchema,
+ AxContextSchema.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + key.getId() + DOES_NOT_EXIST);
+ }
+ }
+
+ final Set<AxContextSchema> schemaSet = apexModel.getPolicyModel().getSchemas().getAll(name, version);
+ if (schemaSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxContextSchema schema : schemaSet) {
+ result.addMessage(
+ new ApexModelStringWriter<AxContextSchema>(false).writeString(schema, AxContextSchema.class));
+ apexModel.getPolicyModel().getSchemas().getSchemasMap().remove(schema.getKey());
+ keyInformationFacade.deleteKeyInformation(name, version);
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Validate context schemas.
+ *
+ * @param name name of the context schema, set to null to list all
+ * @param version starting version of the context schema, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult validateContextSchemas(final String name, final String version) {
+ try {
+ final Set<AxContextSchema> schemaSet = apexModel.getPolicyModel().getSchemas().getAll(name, version);
+ if (schemaSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxContextSchema schema : schemaSet) {
+ final AxValidationResult validationResult = schema.validate(new AxValidationResult());
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(schema.getKey(), AxArtifactKey.class));
+ result.addMessage(validationResult.toString());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/CreatePolicyStateTaskRef.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/CreatePolicyStateTaskRef.java
new file mode 100644
index 000000000..a6e4c334e
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/CreatePolicyStateTaskRef.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Samsung Electronics Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi.impl;
+
+import lombok.Builder;
+import lombok.Getter;
+
+@Getter
+@Builder
+public class CreatePolicyStateTaskRef {
+ private String name;
+ private String version;
+ private String stateName;
+ private String taskLocalName;
+ private String taskName;
+ private String taskVersion;
+ private String outputType;
+ private String outputName;
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/EventFacade.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/EventFacade.java
new file mode 100644
index 000000000..336f27b5d
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/EventFacade.java
@@ -0,0 +1,386 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model for event operations
+ * operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class EventFacade {
+ private static final String CONCEPT = "concept ";
+ private static final String CONCEPT_S = "concept(s) ";
+ private static final String DOES_NOT_EXIST = " does not exist";
+ private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+ private static final String ALREADY_EXISTS = " already exists";
+
+ // Apex model we're working towards
+ private final ApexModel apexModel;
+
+ // Properties to use for the model
+ private final Properties apexProperties;
+
+ // Facade classes for working towards the real Apex model
+ private final KeyInformationFacade keyInformationFacade;
+
+ /**
+ * Constructor to create an event facade for the Model API.
+ *
+ * @param apexModel the apex model
+ * @param apexProperties Properties for the model
+ */
+ public EventFacade(final ApexModel apexModel, final Properties apexProperties) {
+ this.apexModel = apexModel;
+ this.apexProperties = apexProperties;
+
+ keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties);
+ }
+
+ /**
+ * Create an event.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to use the default version
+ * @param nameSpace of the event, set to null to use the default value
+ * @param source of the event, set to null to use the default value
+ * @param target of the event, set to null to use the default value
+ * @param uuid event UUID, set to null to generate a UUID
+ * @param description event description, set to null to generate a description
+ * @param toscaPolicyState specifies TOSCA policy processing status
+ * @return result of the operation
+ */
+ public ApexApiResult createEvent(final String name, final String version, final String nameSpace,
+ final String source, final String target, final String uuid, final String description,
+ final String toscaPolicyState) {
+ try {
+ final AxArtifactKey key = new AxArtifactKey();
+ key.setName(name);
+ if (version != null) {
+ key.setVersion(version);
+ } else {
+ key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+ }
+
+ if (apexModel.getPolicyModel().getEvents().getEventMap().containsKey(key)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, CONCEPT + key.getId() + ALREADY_EXISTS);
+ }
+
+ final AxEvent event = new AxEvent(key);
+
+ event.setNameSpace((nameSpace != null ? nameSpace : apexProperties.getProperty("DEFAULT_EVENT_NAMESPACE")));
+ event.setSource((source != null ? source : apexProperties.getProperty("DEFAULT_EVENT_SOURCE")));
+ event.setTarget((target != null ? target : apexProperties.getProperty("DEFAULT_EVENT_TARGET")));
+ if (toscaPolicyState != null) {
+ event.setToscaPolicyState(toscaPolicyState);
+ }
+
+ apexModel.getPolicyModel().getEvents().getEventMap().put(key, event);
+
+ if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } else {
+ return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update an event.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to use the latest version
+ * @param nameSpace of the event, set to null to not update
+ * @param source of the event, set to null to not update
+ * @param target of the event, set to null to not update
+ * @param uuid event UUID, set to null to not update
+ * @param description event description, set to null to not update
+ * @param toscaPolicyState specifies TOSCA policy processing status
+ * @return result of the operation
+ */
+ public ApexApiResult updateEvent(final String name, final String version, final String nameSpace,
+ final String source, final String target, final String uuid, final String description,
+ final String toscaPolicyState) {
+ try {
+ final AxEvent event = apexModel.getPolicyModel().getEvents().get(name, version);
+ if (event == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ if (nameSpace != null) {
+ event.setNameSpace(nameSpace);
+ }
+ if (source != null) {
+ event.setSource(source);
+ }
+ if (target != null) {
+ event.setTarget(target);
+ }
+ if (toscaPolicyState != null) {
+ event.setToscaPolicyState(toscaPolicyState);
+ }
+
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List events.
+ *
+ * @param name name of the event, set to null to list all
+ * @param version starting version of the event, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult listEvent(final String name, final String version) {
+ try {
+ final Set<AxEvent> eventSet = apexModel.getPolicyModel().getEvents().getAll(name, version);
+ if (name != null && eventSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxEvent event : eventSet) {
+ result.addMessage(new ApexModelStringWriter<AxEvent>(false).writeString(event, AxEvent.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete an event.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to delete all versions
+ * @return result of the operation
+ */
+ public ApexApiResult deleteEvent(final String name, final String version) {
+ try {
+ if (version != null) {
+ final AxArtifactKey key = new AxArtifactKey(name, version);
+ final AxEvent removedEvent = apexModel.getPolicyModel().getEvents().getEventMap().remove(key);
+ if (removedEvent != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxEvent>(false).writeString(removedEvent, AxEvent.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + key.getId() + DOES_NOT_EXIST);
+ }
+ }
+
+ final Set<AxEvent> eventSet = apexModel.getPolicyModel().getEvents().getAll(name, version);
+ if (eventSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxEvent event : eventSet) {
+ result.addMessage(new ApexModelStringWriter<AxEvent>(false).writeString(event, AxEvent.class));
+ apexModel.getPolicyModel().getEvents().getEventMap().remove(event.getKey());
+ keyInformationFacade.deleteKeyInformation(name, version);
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Validate events.
+ *
+ * @param name name of the event, set to null to list all
+ * @param version starting version of the event, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult validateEvent(final String name, final String version) {
+ try {
+ final Set<AxEvent> eventSet = apexModel.getPolicyModel().getEvents().getAll(name, version);
+ if (eventSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxEvent event : eventSet) {
+ final AxValidationResult validationResult = event.validate(new AxValidationResult());
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(event.getKey(), AxArtifactKey.class));
+ result.addMessage(validationResult.toString());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create an event parameter.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to use the latest version
+ * @param parName of the parameter
+ * @param contextSchemaName name of the parameter context schema
+ * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+ * latest version
+ * @param optional true if the event parameter is optional, false otherwise
+ * @return result of the operation
+ */
+ public ApexApiResult createEventPar(final String name, final String version, final String parName,
+ final String contextSchemaName, final String contextSchemaVersion, final boolean optional) {
+ try {
+ Assertions.argumentNotNull(parName, "parName may not be null");
+
+ final AxEvent event = apexModel.getPolicyModel().getEvents().get(name, version);
+ if (event == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxReferenceKey refKey = new AxReferenceKey(event.getKey(), parName);
+
+ if (event.getParameterMap().containsKey(refKey.getLocalName())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ CONCEPT + refKey.getId() + ALREADY_EXISTS);
+ }
+
+ final AxContextSchema schema =
+ apexModel.getPolicyModel().getSchemas().get(contextSchemaName, contextSchemaVersion);
+ if (schema == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + contextSchemaName + ':' + contextSchemaVersion + DOES_NOT_EXIST);
+ }
+
+ event.getParameterMap().put(refKey.getLocalName(), new AxField(refKey, schema.getKey(), optional));
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List event parameters.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to list latest version
+ * @param parName name of the parameter, set to null to list all parameters of the event
+ * @return result of the operation
+ */
+ public ApexApiResult listEventPar(final String name, final String version, final String parName) {
+ try {
+ final AxEvent event = apexModel.getPolicyModel().getEvents().get(name, version);
+ if (event == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ if (parName != null) {
+ final AxField eventField = event.getParameterMap().get(parName);
+ if (eventField != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxField>(false).writeString(eventField, AxField.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + ':' + parName + DOES_NOT_EXIST);
+ }
+ } else {
+ if (event.getParameterMap().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no parameters defined on event " + event.getKey().getId());
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxField eventPar : event.getParameterMap().values()) {
+ result.addMessage(new ApexModelStringWriter<AxField>(false).writeString(eventPar, AxField.class));
+ }
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete an event parameter.
+ *
+ * @param name name of the event
+ * @param version version of the event, set to null to use the latest version
+ * @param parName of the parameter, set to null to delete all parameters
+ * @return result of the operation
+ */
+ public ApexApiResult deleteEventPar(final String name, final String version, final String parName) {
+ try {
+ final AxEvent event = apexModel.getPolicyModel().getEvents().get(name, version);
+ if (event == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ if (parName != null) {
+ if (event.getParameterMap().containsKey(parName)) {
+ result.addMessage(new ApexModelStringWriter<AxField>(false)
+ .writeString(event.getParameterMap().get(parName), AxField.class));
+ event.getParameterMap().remove(parName);
+ return result;
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + ':' + parName + DOES_NOT_EXIST);
+ }
+ } else {
+ if (event.getParameterMap().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no parameters defined on event " + event.getKey().getId());
+ }
+
+ for (final AxField eventPar : event.getParameterMap().values()) {
+ result.addMessage(new ApexModelStringWriter<AxField>(false).writeString(eventPar, AxField.class));
+ }
+ event.getParameterMap().clear();
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/KeyInformationFacade.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/KeyInformationFacade.java
new file mode 100644
index 000000000..6875a4c20
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/KeyInformationFacade.java
@@ -0,0 +1,228 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+import lombok.AllArgsConstructor;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+
+/**
+ * This class acts as a facade for operations towards a policy model for key information operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+@AllArgsConstructor
+public class KeyInformationFacade {
+ private static final String CONCEPT = "concept ";
+ private static final String CONCEPT_S = "concept(s) ";
+ private static final String DOES_NOT_EXIST = " does not exist";
+ private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+ private static final String ALREADY_EXISTS = " already exists";
+
+ // Apex model we're working towards
+ private final ApexModel apexModel;
+
+ // Properties to use for the model
+ private final Properties apexProperties;
+
+ /**
+ * Create key information.
+ *
+ * @param name name of the concept for the key information
+ * @param version version of the concept for the key information, set to null to use the default
+ * version
+ * @param uuid key information UUID, set to null to generate a UUID
+ * @param description key information description, set to null to generate a description
+ * @return result of the operation
+ */
+ public ApexApiResult createKeyInformation(final String name, final String version, final String uuid,
+ final String description) {
+ try {
+ final AxArtifactKey key = new AxArtifactKey();
+ key.setName(name);
+ if (version != null) {
+ key.setVersion(version);
+ } else {
+ key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+ }
+
+ if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, CONCEPT + key.getId() + ALREADY_EXISTS);
+ }
+
+ final AxKeyInfo keyInfo = new AxKeyInfo(key);
+ if (description != null) {
+ keyInfo.setDescription(description);
+ }
+ if (uuid != null) {
+ keyInfo.setUuid(UUID.fromString(uuid));
+ } else {
+ // generate a reproducible UUID
+ keyInfo.setUuid(AxKeyInfo.generateReproducibleUuid(keyInfo.getId() + keyInfo.getDescription()));
+ }
+ apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().put(key, keyInfo);
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update key information.
+ *
+ * @param name name of the concept for the key information
+ * @param version version of the concept for the key information, set to null to update the
+ * latest version
+ * @param uuid key information UUID, set to null to not update
+ * @param description key information description, set to null to not update
+ * @return result of the operation
+ */
+ public ApexApiResult updateKeyInformation(final String name, final String version, final String uuid,
+ final String description) {
+ try {
+ final AxKeyInfo keyInfo = apexModel.getPolicyModel().getKeyInformation().get(name, version);
+ if (keyInfo == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ":" + version + DOES_NOT_EXIST);
+ }
+
+ if (description != null) {
+ keyInfo.setDescription(description);
+ }
+
+ if (uuid != null) {
+ keyInfo.setUuid(UUID.fromString(uuid));
+ } else {
+ // generate a reproducible UUID
+ keyInfo.setUuid(AxKeyInfo.generateReproducibleUuid(keyInfo.getId() + keyInfo.getDescription()));
+ }
+
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List key information.
+ *
+ * @param name name of the concept for the key information, set to null to list all
+ * @param version starting version of the concept for the key information, set to null to list
+ * all versions
+ * @return result of the operation
+ */
+ public ApexApiResult listKeyInformation(final String name, final String version) {
+ try {
+ final Set<AxKeyInfo> keyInfoSet = apexModel.getPolicyModel().getKeyInformation().getAll(name, version);
+ if (name != null && keyInfoSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxKeyInfo keyInfo : keyInfoSet) {
+ result.addMessage(new ApexModelStringWriter<AxKeyInfo>(false).writeString(keyInfo, AxKeyInfo.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete key information.
+ *
+ * @param name name of the concept for the key information
+ * @param version version of the concept for the key information, set to null to delete all
+ * versions
+ * @return result of the operation
+ */
+ public ApexApiResult deleteKeyInformation(final String name, final String version) {
+ try {
+ if (version != null) {
+ final AxArtifactKey key = new AxArtifactKey(name, version);
+ final AxKeyInfo removedKeyInfo =
+ apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().remove(key);
+ if (removedKeyInfo != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxKeyInfo>(false).writeString(removedKeyInfo, AxKeyInfo.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + key.getId() + DOES_NOT_EXIST);
+ }
+ }
+
+ final Set<AxKeyInfo> keyInfoSet = apexModel.getPolicyModel().getKeyInformation().getAll(name, version);
+ if (keyInfoSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxKeyInfo keyInfo : keyInfoSet) {
+ result.addMessage(new ApexModelStringWriter<AxKeyInfo>(false).writeString(keyInfo, AxKeyInfo.class));
+ apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().remove(keyInfo.getKey());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Validate key information.
+ *
+ * @param name name of the concept for the key information
+ * @param version version of the concept for the key information, set to null to validate all
+ * versions
+ * @return result of the operation
+ */
+ public ApexApiResult validateKeyInformation(final String name, final String version) {
+ try {
+ final Set<AxKeyInfo> keyInfoSet = apexModel.getPolicyModel().getKeyInformation().getAll(name, version);
+ if (keyInfoSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxKeyInfo keyInfo : keyInfoSet) {
+ final AxValidationResult validationResult = keyInfo.validate(new AxValidationResult());
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyInfo.getKey(), AxArtifactKey.class));
+ result.addMessage(validationResult.toString());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelFacade.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelFacade.java
new file mode 100644
index 000000000..1030a5bf5
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelFacade.java
@@ -0,0 +1,202 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,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.onap.policy.apex.model.modelapi.impl;
+
+import java.util.Properties;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ModelFacade {
+ private static final String CONCEPT = "concept ";
+ private static final String DOES_NOT_EXIST = " does not exist";
+ private static final String ALREADY_CREATED = " already created";
+ private static final String NO_VERSION_SPECIFIED = ", no version specified";
+
+ // Apex model we're working towards
+ private final ApexModel apexModel;
+
+ // Properties to use for the model
+ private final Properties apexProperties;
+
+ // Facade classes for working towards the real Apex model
+ private final KeyInformationFacade keyInformationFacade;
+
+ /**
+ * Constructor to create a model facade for the Apex model.
+ *
+ * @param apexModel the apex model
+ * @param apexProperties Properties for the model
+ */
+ public ModelFacade(final ApexModel apexModel, final Properties apexProperties) {
+ Assertions.argumentNotNull(apexModel, "apexModel may not be null");
+ Assertions.argumentNotNull(apexProperties, "apexProperties may not be null");
+
+ this.apexModel = apexModel;
+ this.apexProperties = apexProperties;
+
+ keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties);
+ }
+
+ /**
+ * Create model.
+ *
+ * @param name name of the model
+ * @param version version of the model, set to null to use the default version
+ * @param uuid model UUID, set to null to generate a UUID
+ * @param description model description, set to null to generate a description
+ * @return result of the operation
+ */
+ public ApexApiResult createModel(final String name, final String version, final String uuid,
+ final String description) {
+ try {
+ final AxArtifactKey key = new AxArtifactKey();
+ key.setName(name);
+ if (version != null) {
+ key.setVersion(version);
+ } else {
+ final String defaultVersion = apexProperties.getProperty("DEFAULT_CONCEPT_VERSION");
+ if (defaultVersion != null) {
+ key.setVersion(defaultVersion);
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, CONCEPT + name + NO_VERSION_SPECIFIED);
+ }
+ }
+
+ if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ CONCEPT + apexModel.getPolicyModel().getKey().getId() + ALREADY_CREATED);
+ }
+
+ apexModel.setPolicyModel(new AxPolicyModel(key));
+
+ ApexApiResult result;
+
+ result = keyInformationFacade.createKeyInformation(name, version, uuid, description);
+ if (result.getResult().equals(ApexApiResult.Result.SUCCESS)) {
+ apexModel.getPolicyModel().buildReferences();
+ apexModel.getPolicyModel().getKeyInformation().generateKeyInfo(apexModel.getPolicyModel());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update model.
+ *
+ * @param name name of the model
+ * @param version version of the model, set to null to update the latest version
+ * @param uuid key information UUID, set to null to not update
+ * @param description policy description, set to null to not update
+ * @return result of the operation
+ */
+ public ApexApiResult updateModel(final String name, final String version, final String uuid,
+ final String description) {
+ try {
+ final AxArtifactKey key = new AxArtifactKey();
+ key.setName(name);
+ if (version != null) {
+ key.setVersion(version);
+ } else {
+ final String defaultVersion = apexProperties.getProperty("DEFAULT_CONCEPT_VERSION");
+ if (defaultVersion != null) {
+ key.setVersion(defaultVersion);
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.FAILED,
+ CONCEPT + apexModel.getPolicyModel().getKey().getId() + NO_VERSION_SPECIFIED);
+ }
+ }
+
+ if (apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + apexModel.getPolicyModel().getKey().getId() + DOES_NOT_EXIST);
+ }
+
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Get the key of an Apex model.
+ *
+ * @return the result of the operation
+ */
+ public ApexApiResult getModelKey() {
+ try {
+ final ApexApiResult result = new ApexApiResult();
+ final AxArtifactKey modelkey = apexModel.getPolicyModel().getKey();
+ result
+ .addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(modelkey, AxArtifactKey.class));
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List an Apex model.
+ *
+ * @return the result of the operation
+ */
+ public ApexApiResult listModel() {
+ try {
+ final ApexApiResult result = new ApexApiResult();
+ result.addMessage(new ApexModelStringWriter<AxPolicyModel>(false).writeString(apexModel.getPolicyModel(),
+ AxPolicyModel.class));
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete an Apex model, clear all the concepts in the model.
+ *
+ * @return the result of the operation
+ */
+ public ApexApiResult deleteModel() {
+ // @formatter:off
+ apexModel.getPolicyModel().getSchemas().getSchemasMap().clear();
+ apexModel.getPolicyModel().getEvents().getEventMap().clear();
+ apexModel.getPolicyModel().getAlbums().getAlbumsMap().clear();
+ apexModel.getPolicyModel().getTasks().getTaskMap().clear();
+ apexModel.getPolicyModel().getPolicies().getPolicyMap().clear();
+ apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().clear();
+ // @formatter:on
+
+ apexModel.setPolicyModel(new AxPolicyModel());
+
+ return new ApexApiResult();
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java
new file mode 100644
index 000000000..fecf92e1f
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java
@@ -0,0 +1,498 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,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.onap.policy.apex.model.modelapi.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.util.LinkedHashSet;
+import java.util.Properties;
+import java.util.Set;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelFileWriter;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelWriter;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.handling.PolicyAnalyser;
+import org.onap.policy.apex.model.policymodel.handling.PolicyAnalysisResult;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelComparer;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelMerger;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelSplitter;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+import org.onap.policy.common.utils.validation.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class acts as a facade for model handling for the Apex Model API.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ModelHandlerFacade {
+ private static final String FILE_NAME_MAY_NOT_BE_NULL = "fileName may not be null";
+ private static final String MODEL = "model ";
+ private static final String ALREADY_LOADED = " already loaded";
+
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ModelHandlerFacade.class);
+
+ // Apex model we're working towards
+ private final ApexModel apexModel;
+
+ /**
+ * This Constructor creates a model handling facade for the given {@link ApexModel}.
+ *
+ * @param apexModel the apex model to manipulate
+ * @param apexProperties properties for the model
+ */
+ public ModelHandlerFacade(final ApexModel apexModel, final Properties apexProperties) {
+ Assertions.argumentNotNull(apexModel, "apexModel may not be null");
+ Assertions.argumentNotNull(apexProperties, "apexProperties may not be null");
+
+ this.apexModel = apexModel;
+ }
+
+ /**
+ * Load an Apex model from a string.
+ *
+ * @param modelString the string with the model
+ * @return the result of the operation
+ */
+ public ApexApiResult loadFromString(final String modelString) {
+ Assertions.argumentNotNull(modelString, "modelString may not be null");
+
+ if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ MODEL + apexModel.getPolicyModel().getKey().getId() + ALREADY_LOADED);
+ }
+
+ ApexApiResult result = new ApexApiResult();
+ AxPolicyModel newPolicyModel = loadModelFromString(modelString, result);
+ apexModel.setPolicyModel(newPolicyModel != null ? newPolicyModel : new AxPolicyModel());
+
+ return result;
+ }
+
+ /**
+ * Load an Apex model from a file.
+ *
+ * @param fileName the file name of the file with the model
+ * @return the result of the operation
+ */
+ public ApexApiResult loadFromFile(final String fileName) {
+ Assertions.argumentNotNull(fileName, FILE_NAME_MAY_NOT_BE_NULL);
+
+ if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ MODEL + apexModel.getPolicyModel().getKey().getId() + ALREADY_LOADED);
+ }
+
+ ApexApiResult result = new ApexApiResult();
+ AxPolicyModel newPolicyModel = loadModelFromFile(fileName, result);
+ apexModel.setPolicyModel(newPolicyModel != null ? newPolicyModel : new AxPolicyModel());
+
+ return result;
+ }
+
+ /**
+ * Save an Apex model to a file.
+ *
+ * @param fileName the file name
+ * @return the result of the operation
+ */
+ public ApexApiResult saveToFile(final String fileName) {
+ Assertions.argumentNotNull(fileName, FILE_NAME_MAY_NOT_BE_NULL);
+
+ ApexModelFileWriter<AxPolicyModel> apexModelFileWriter = new ApexModelFileWriter<>(false);
+
+ try {
+ apexModelFileWriter.apexModelWriteJsonFile(apexModel.getPolicyModel(), AxPolicyModel.class, fileName);
+ return new ApexApiResult();
+ } catch (ApexException e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Read an APEX model from a location identified by a URL.
+ *
+ * @param urlString the url string
+ * @return the result of the operation
+ */
+ public ApexApiResult readFromUrl(final String urlString) {
+ Assertions.argumentNotNull(urlString, "urlString may not be null");
+
+ if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ MODEL + apexModel.getPolicyModel().getKey().getId() + ALREADY_LOADED);
+ }
+
+ URL apexModelUrl;
+ try {
+ apexModelUrl = new URL(urlString);
+ } catch (MalformedURLException e) {
+ ApexApiResult result = new ApexApiResult(ApexApiResult.Result.FAILED);
+ result.addMessage("URL string " + urlString + " is not a valid URL");
+ result.addThrowable(e);
+ return result;
+ }
+
+ try {
+ ApexModelReader<AxPolicyModel> apexModelReader = new ApexModelReader<>(AxPolicyModel.class);
+ apexModelReader.setValidate(false);
+ AxPolicyModel newPolicyModel = apexModelReader.read(apexModelUrl.openStream());
+ apexModel.setPolicyModel(newPolicyModel != null ? newPolicyModel : new AxPolicyModel());
+ return new ApexApiResult();
+ } catch (ApexModelException | IOException e) {
+ apexModel.setPolicyModel(new AxPolicyModel());
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Write an APEX model to a location identified by a URL.
+ *
+ * @param urlString the URL to read the model from
+ * @return the result of the operation
+ */
+ public ApexApiResult writeToUrl(final String urlString) {
+ Assertions.argumentNotNull(urlString, "urlString may not be null");
+
+ URL apexModelUrl;
+ try {
+ apexModelUrl = new URL(urlString);
+ } catch (MalformedURLException e) {
+ ApexApiResult result = new ApexApiResult(ApexApiResult.Result.FAILED);
+ result.addMessage("URL string " + urlString + " is not a valid URL");
+ result.addThrowable(e);
+ return result;
+ }
+
+ try {
+ ApexModelWriter<AxPolicyModel> apexModelWriter = new ApexModelWriter<>(AxPolicyModel.class);
+ apexModelWriter.setValidate(false);
+
+ // Open the URL for output and write the model
+ URLConnection urlConnection = apexModelUrl.openConnection();
+ urlConnection.setDoOutput(true);
+
+ apexModelWriter.write(apexModel.getPolicyModel(), urlConnection.getOutputStream());
+ return new ApexApiResult();
+ } catch (ApexModelException | IOException e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Analyse an Apex model that shows the concept usage references of a policy model.
+ *
+ * @return the result of the operation
+ */
+ public ApexApiResult analyse() {
+ PolicyAnalysisResult analysisResult = new PolicyAnalyser().analyse(apexModel.getPolicyModel());
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS, analysisResult.toString());
+ }
+
+ /**
+ * Validate an Apex model, checking all concepts and references in the model.
+ *
+ * @return the result of the operation
+ */
+ public ApexApiResult validate() {
+ ApexApiResult result = new ApexApiResult();
+ try {
+ AxValidationResult validationResult = apexModel.getPolicyModel().validate(new AxValidationResult());
+
+ if (!validationResult.isValid()) {
+ result.setResult(ApexApiResult.Result.FAILED);
+ }
+ result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false)
+ .writeString(apexModel.getPolicyModel().getKey(), AxArtifactKey.class));
+ result.addMessage(validationResult.toString());
+ return result;
+ } catch (Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Compare to Apex models, returning the differences between the models.
+ *
+ * @param otherModelFileName the file name of the other model
+ * @param diffsOnly only returns differences between the model when set
+ * @param keysOnly only returns the keys that are different when set, when not set values are also returned
+ * @return the result of the operation
+ */
+ public ApexApiResult compare(final String otherModelFileName, final boolean diffsOnly, final boolean keysOnly) {
+ ApexApiResult result = new ApexApiResult();
+ try {
+ AxPolicyModel otherPolicyModel = loadModelFromFile(otherModelFileName, result);
+ if (!result.getResult().equals(ApexApiResult.Result.SUCCESS)) {
+ return result;
+ }
+
+ PolicyModelComparer policyModelComparer =
+ new PolicyModelComparer(apexModel.getPolicyModel(), otherPolicyModel);
+ result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false)
+ .writeString(apexModel.getPolicyModel().getKey(), AxArtifactKey.class));
+ result.addMessage(policyModelComparer.toString());
+
+ return result;
+ } catch (Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Compare two Apex models, returning the differences between the models.
+ *
+ * @param otherModelString the other model as a string
+ * @param diffsOnly only returns differences between the model when set
+ * @param keysOnly only returns the keys that are different when set, when not set values are also returned
+ * @return the result of the operation
+ */
+ public ApexApiResult compareWithString(final String otherModelString, final boolean diffsOnly,
+ final boolean keysOnly) {
+ ApexApiResult result = new ApexApiResult();
+ try {
+ AxPolicyModel otherPolicyModel = loadModelFromString(otherModelString, result);
+ if (!result.getResult().equals(ApexApiResult.Result.SUCCESS)) {
+ return result;
+ }
+
+ PolicyModelComparer policyModelComparer =
+ new PolicyModelComparer(apexModel.getPolicyModel(), otherPolicyModel);
+ result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false)
+ .writeString(apexModel.getPolicyModel().getKey(), AxArtifactKey.class));
+ result.addMessage(policyModelComparer.toString());
+
+ return result;
+ } catch (Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Split out a sub model from an Apex model that contains a given subset of the policies in the original model.
+ *
+ * @param targetModelName the file name of the target model in which to store the model split out from the original
+ * model
+ * @param splitOutPolicies the policies form the original model to include in the split out model, specified as a
+ * comma delimited list of policy names
+ * @return the result of the operation
+ */
+ public ApexApiResult split(final String targetModelName, final String splitOutPolicies) {
+ Set<AxArtifactKey> requiredPolicySet = new LinkedHashSet<>();
+
+ // Split the policy names on comma
+ String[] policyNames = splitOutPolicies.split(",");
+
+ // Iterate over the policy names
+ for (String policyName : policyNames) {
+ // Split out this specific policy
+ AxPolicy requiredPolicy = apexModel.getPolicyModel().getPolicies().get(policyName);
+
+ if (requiredPolicy != null) {
+ requiredPolicySet.add(requiredPolicy.getKey());
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.FAILED,
+ "policy for policy name " + policyName + " not found in model");
+ }
+ }
+
+ try {
+ AxPolicyModel splitPolicyModel =
+ PolicyModelSplitter.getSubPolicyModel(apexModel.getPolicyModel(), requiredPolicySet, false);
+
+ ApexModelFileWriter<AxPolicyModel> apexModelFileWriter = new ApexModelFileWriter<>(false);
+ apexModelFileWriter.apexModelWriteJsonFile(splitPolicyModel, AxPolicyModel.class, targetModelName);
+ return new ApexApiResult();
+ } catch (ApexException e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Split out a sub model from an Apex model that contains a given subset of the policies in the original model,
+ * return the split model in the result as a string.
+ *
+ * @param splitOutPolicies the policies form the original model to include in the split out model, specified as a
+ * comma delimited list of policy names
+ * @return the result of the operation
+ */
+ public ApexApiResult split(final String splitOutPolicies) {
+ ApexApiResult splitResult = new ApexApiResult();
+ File tempSplitPolicyFile = null;
+ try {
+ tempSplitPolicyFile = TextFileUtils.createTempFile("ApexTempPolicy", null);
+
+ // Split the policy into a temporary file
+ splitResult = split(tempSplitPolicyFile.getCanonicalPath(), splitOutPolicies);
+ if (splitResult.isNok()) {
+ return splitResult;
+ }
+
+ // Get the policy model into a string
+ String splitPolicyModelString = TextFileUtils.getTextFileAsString(tempSplitPolicyFile.getCanonicalPath());
+
+ // Return the policy model
+ splitResult.addMessage(splitPolicyModelString);
+ return splitResult;
+ } catch (Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED,
+ "split of policy model " + apexModel.getPolicyModel().getId() + " failed", e);
+ } finally {
+ if (tempSplitPolicyFile != null) {
+ try {
+ Files.delete(tempSplitPolicyFile.toPath());
+ } catch (IOException e) {
+ LOGGER.debug("delete of temporary file failed", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Merge two Apex models together.
+ *
+ * @param mergeInModelName the file name of the model to merge into the current model
+ * @param keepOriginal if this flag is set to true, if a concept exists in both models, the original model copy of
+ * that concept is kept, if the flag is set to false, then the copy of the concept from the mergeInModel
+ * overwrites the concept in the original model
+ * @return the result of the operation
+ */
+ public ApexApiResult merge(final String mergeInModelName, final boolean keepOriginal) {
+ ApexApiResult result = new ApexApiResult();
+ AxPolicyModel mergeInPolicyModel = loadModelFromFile(mergeInModelName, result);
+ if (!result.getResult().equals(ApexApiResult.Result.SUCCESS)) {
+ return result;
+ }
+
+ try {
+ AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(apexModel.getPolicyModel(),
+ mergeInPolicyModel, keepOriginal, false, false);
+ apexModel.setPolicyModel(mergedPolicyModel != null ? mergedPolicyModel : new AxPolicyModel());
+ return new ApexApiResult();
+ } catch (ApexModelException e) {
+ apexModel.setPolicyModel(new AxPolicyModel());
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Merge two Apex models together.
+ *
+ * @param otherModelString the model to merge as a string
+ * @param keepOriginal if this flag is set to true, if a concept exists in both models, the original model copy of
+ * that concept is kept, if the flag is set to false, then the copy of the concept from the mergeInModel
+ * overwrites the concept in the original model
+ * @return the result of the operation
+ */
+ public ApexApiResult mergeWithString(final String otherModelString, final boolean keepOriginal) {
+ ApexApiResult result = new ApexApiResult();
+ AxPolicyModel mergeInPolicyModel = loadModelFromString(otherModelString, result);
+ if (!result.getResult().equals(ApexApiResult.Result.SUCCESS)) {
+ return result;
+ }
+
+ try {
+ AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(apexModel.getPolicyModel(),
+ mergeInPolicyModel, keepOriginal, false, false);
+ apexModel.setPolicyModel(mergedPolicyModel != null ? mergedPolicyModel : new AxPolicyModel());
+ return new ApexApiResult();
+ } catch (ApexModelException e) {
+ apexModel.setPolicyModel(new AxPolicyModel());
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Load a policy model from a file.
+ *
+ * @param fileName the name of the file containing the model
+ * @param result the result of the operation
+ * @return the model
+ */
+ private AxPolicyModel loadModelFromFile(final String fileName, final ApexApiResult result) {
+ Assertions.argumentNotNull(fileName, FILE_NAME_MAY_NOT_BE_NULL);
+
+ AxPolicyModel readModel = null;
+
+ final URL apexModelUrl = ResourceUtils.getLocalFile(fileName);
+ if (apexModelUrl == null) {
+ result.setResult(ApexApiResult.Result.FAILED);
+ result.addMessage("file " + fileName + " not found");
+ return null;
+ }
+
+ try {
+ ApexModelReader<AxPolicyModel> apexModelReader = new ApexModelReader<>(AxPolicyModel.class);
+ apexModelReader.setValidate(false);
+ readModel = apexModelReader.read(apexModelUrl.openStream());
+ result.setResult(ApexApiResult.Result.SUCCESS);
+ return readModel;
+ } catch (Exception e) {
+ result.setResult(ApexApiResult.Result.FAILED);
+ result.addThrowable(e);
+ return null;
+ }
+ }
+
+ /**
+ * Load a policy model from a string.
+ *
+ * @param modelString the string containing the model
+ * @param result the result of the operation
+ * @return the model
+ */
+ private AxPolicyModel loadModelFromString(final String modelString, final ApexApiResult result) {
+ Assertions.argumentNotNull(modelString, "modelString may not be null");
+
+ AxPolicyModel readModel = null;
+
+ InputStream modelStringStream = new ByteArrayInputStream(modelString.getBytes());
+
+ try {
+ ApexModelReader<AxPolicyModel> apexModelReader = new ApexModelReader<>(AxPolicyModel.class);
+ apexModelReader.setValidate(false);
+ readModel = apexModelReader.read(modelStringStream);
+ result.setResult(ApexApiResult.Result.SUCCESS);
+ return readModel;
+ } catch (Exception e) {
+ result.setResult(ApexApiResult.Result.FAILED);
+ result.addThrowable(e);
+ return null;
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/PolicyFacade.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/PolicyFacade.java
new file mode 100644
index 000000000..408f0913f
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/PolicyFacade.java
@@ -0,0 +1,1385 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi.impl;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxState;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model for policy operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyFacade {
+ private static final String STATE_NAME_MAY_NOT_BE_NULL = "stateName may not be null";
+ private static final String DOES_NOT_EXIST_ON_STATE = " does not exist on state ";
+ private static final String STATE_FINALIZER_LOGIC = "state finalizer logic ";
+ private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+ private static final String CONCEPT_S = "concept(s) ";
+ private static final String DOES_NOT_EXIST = " does not exist";
+ private static final String CONCEPT = "concept ";
+ private static final String ALREADY_EXISTS = " already exists";
+
+ // Apex model we're working towards
+ private final ApexModel apexModel;
+
+ // Properties to use for the model
+ private final Properties apexProperties;
+
+ // Facade classes for working towards the real Apex model
+ private final KeyInformationFacade keyInformationFacade;
+
+ /**
+ * Constructor that creates a policy facade for the Apex Model API.
+ *
+ * @param apexModel the apex model
+ * @param apexProperties Properties for the model
+ */
+ public PolicyFacade(final ApexModel apexModel, final Properties apexProperties) {
+ this.apexModel = apexModel;
+ this.apexProperties = apexProperties;
+
+ keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties);
+ }
+
+ /**
+ * Create a policy.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the default version
+ * @param template template used to create the policy, set to null to use the default template
+ * @param firstState the first state of the policy
+ * @param uuid policy UUID, set to null to generate a UUID
+ * @param description policy description, set to null to generate a description
+ * @return result of the operation
+ */
+ public ApexApiResult createPolicy(final String name, final String version, final String template,
+ final String firstState, final String uuid, final String description) {
+ try {
+ final AxArtifactKey key = new AxArtifactKey();
+ key.setName(name);
+ if (version != null) {
+ key.setVersion(version);
+ } else {
+ key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+ }
+
+ String templateString = template;
+ if (templateString == null) {
+ templateString = apexProperties.getProperty("DEFAULT_POLICY_TEMPLATE");
+ }
+
+ if (apexModel.getPolicyModel().getPolicies().getPolicyMap().containsKey(key)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, CONCEPT + key.getId() + ALREADY_EXISTS);
+ }
+
+ final AxPolicy policy = new AxPolicy(key);
+ policy.setTemplate(templateString);
+ policy.setFirstState(firstState);
+
+ apexModel.getPolicyModel().getPolicies().getPolicyMap().put(key, policy);
+
+ if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } else {
+ return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update a policy.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param template template used to create the policy, set to null to not update
+ * @param firstState the first state of the policy
+ * @param uuid policy UUID, set to null to not update
+ * @param description policy description, set to null to not update
+ * @return result of the operation
+ */
+ public ApexApiResult updatePolicy(final String name, final String version, final String template,
+ final String firstState, final String uuid, final String description) {
+ try {
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ if (template != null) {
+ policy.setTemplate(template);
+ }
+ if (firstState != null) {
+ policy.setFirstState(firstState);
+ }
+
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List policies.
+ *
+ * @param name name of the policy, set to null to list all
+ * @param version starting version of the policy, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult listPolicy(final String name, final String version) {
+ try {
+ final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
+ if (name != null && policySet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxPolicy policy : policySet) {
+ result.addMessage(new ApexModelStringWriter<AxPolicy>(false).writeString(policy, AxPolicy.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a policy.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult deletePolicy(final String name, final String version) {
+ try {
+ if (version != null) {
+ final AxArtifactKey key = new AxArtifactKey(name, version);
+ final AxPolicy removedPolicy = apexModel.getPolicyModel().getPolicies().getPolicyMap().remove(key);
+ if (removedPolicy != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxPolicy>(false).writeString(removedPolicy, AxPolicy.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + key.getId() + DOES_NOT_EXIST);
+ }
+ }
+
+ final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
+ if (policySet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxPolicy policy : policySet) {
+ result.addMessage(new ApexModelStringWriter<AxPolicy>(false).writeString(policy, AxPolicy.class));
+ apexModel.getPolicyModel().getPolicies().getPolicyMap().remove(policy.getKey());
+ keyInformationFacade.deleteKeyInformation(name, version);
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Validate policies.
+ *
+ * @param name name of the policy, set to null to list all
+ * @param version starting version of the policy, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult validatePolicy(final String name, final String version) {
+ try {
+ final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
+ if (policySet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxPolicy policy : policySet) {
+ final AxValidationResult validationResult = policy.validate(new AxValidationResult());
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(policy.getKey(), AxArtifactKey.class));
+ result.addMessage(validationResult.toString());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create a policy state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param triggerName name of the trigger event for this state
+ * @param triggerVersion version of the trigger event for this state, set to null to use the
+ * latest version
+ * @param defaultTaskName the default task name
+ * @param defaltTaskVersion the default task version, set to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult createPolicyState(final String name, final String version, final String stateName,
+ final String triggerName, final String triggerVersion, final String defaultTaskName,
+ final String defaltTaskVersion) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxReferenceKey refKey = new AxReferenceKey(policy.getKey(), stateName);
+
+ if (policy.getStateMap().containsKey(refKey.getLocalName())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ CONCEPT + refKey.getId() + ALREADY_EXISTS);
+ }
+
+ final AxEvent triggerEvent = apexModel.getPolicyModel().getEvents().get(triggerName, triggerVersion);
+ if (triggerEvent == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + triggerName + ':' + triggerVersion + DOES_NOT_EXIST);
+ }
+
+ final AxTask defaultTask = apexModel.getPolicyModel().getTasks().get(defaultTaskName, defaltTaskVersion);
+ if (defaultTask == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + defaultTaskName + ':' + defaltTaskVersion + DOES_NOT_EXIST);
+ }
+
+ final AxState state = new AxState(refKey);
+ state.setTrigger(triggerEvent.getKey());
+ state.setDefaultTask(defaultTask.getKey());
+
+ policy.getStateMap().put(state.getKey().getLocalName(), state);
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update a policy state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param triggerName name of the trigger event for this state, set to null to not update
+ * @param triggerVersion version of the trigger event for this state, set to use latest version
+ * of trigger event
+ * @param defaultTaskName the default task name, set to null to not update
+ * @param defaltTaskVersion the default task version, set to use latest version of default task
+ * @return result of the operation
+ */
+ public ApexApiResult updatePolicyState(final String name, final String version, final String stateName,
+ final String triggerName, final String triggerVersion, final String defaultTaskName,
+ final String defaltTaskVersion) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ if (triggerName != null) {
+ final AxEvent triggerEvent = apexModel.getPolicyModel().getEvents().get(triggerName, triggerVersion);
+ if (triggerEvent == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + triggerName + ':' + triggerVersion + DOES_NOT_EXIST);
+ }
+ state.setTrigger(triggerEvent.getKey());
+ }
+
+ if (defaultTaskName != null) {
+ final AxTask defaultTask =
+ apexModel.getPolicyModel().getTasks().get(defaultTaskName, defaltTaskVersion);
+ if (defaultTask == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + defaultTaskName + ':' + defaltTaskVersion + DOES_NOT_EXIST);
+ }
+ state.setDefaultTask(defaultTask.getKey());
+ }
+
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List policy states.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state, set to null to list all states of the policy
+ * @return result of the operation
+ */
+ public ApexApiResult listPolicyState(final String name, final String version, final String stateName) {
+ try {
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ if (stateName != null) {
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + ':' + state + DOES_NOT_EXIST);
+ }
+ } else {
+ if (policy.getStateMap().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no states defined on policy " + policy.getKey().getId());
+ }
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxState state : policy.getStateMap().values()) {
+ result.addMessage(new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class));
+ }
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a policy state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state, set to null to delete all states
+ * @return result of the operation
+ */
+ public ApexApiResult deletePolicyState(final String name, final String version, final String stateName) {
+ try {
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ if (stateName != null) {
+ if (policy.getStateMap().containsKey(stateName)) {
+ result.addMessage(new ApexModelStringWriter<AxState>(false)
+ .writeString(policy.getStateMap().get(stateName), AxState.class));
+ policy.getStateMap().remove(stateName);
+ return result;
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + ':' + stateName + DOES_NOT_EXIST);
+ }
+ } else {
+ if (policy.getStateMap().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no states defined on policy " + policy.getKey().getId());
+ }
+ for (final AxState state : policy.getStateMap().values()) {
+ result.addMessage(new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class));
+ }
+ policy.getStateMap().clear();
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create task selection logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param logicFlavour the task selection logic flavour for the state, set to null to use the
+ * default task logic flavour
+ * @param logic the source code for the logic of the state
+ * @return result of the operation
+ */
+ public ApexApiResult createPolicyStateTaskSelectionLogic(final String name, final String version,
+ final String stateName, final String logicFlavour, final String logic) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ // There is only one logic item associated with a state so we use a hard coded logic
+ // name
+ final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), "TaskSelectionLogic");
+
+ if (!state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ CONCEPT + refKey.getId() + ALREADY_EXISTS);
+ }
+
+ state.setTaskSelectionLogic(new AxTaskSelectionLogic(refKey, logicFlavour, logic));
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update task selection logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param logicFlavour the task selection logic flavour for the state, set to null to not update
+ * @param logic the source code for the logic of the state, set to null to not update
+ * @return result of the operation
+ */
+ public ApexApiResult updatePolicyStateTaskSelectionLogic(final String name, final String version,
+ final String stateName, final String logicFlavour, final String logic) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ if (state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + state.getTaskSelectionLogic().getKey().getId() + DOES_NOT_EXIST);
+ }
+
+ final AxTaskSelectionLogic taskSelectionLogic = state.getTaskSelectionLogic();
+ if (logicFlavour != null) {
+ taskSelectionLogic.setLogicFlavour(logicFlavour);
+ }
+ if (logic != null) {
+ taskSelectionLogic.setLogic(logic);
+ }
+
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List task selection logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @return result of the operation
+ */
+ public ApexApiResult listPolicyStateTaskSelectionLogic(final String name, final String version,
+ final String stateName) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxTaskSelectionLogic>(false).writeString(state.getTaskSelectionLogic(),
+ AxTaskSelectionLogic.class));
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete task selection logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @return result of the operation
+ */
+ public ApexApiResult deletePolicyStateTaskSelectionLogic(final String name, final String version,
+ final String stateName) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ if (state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + state.getTaskSelectionLogic().getKey().getId() + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ result.addMessage(new ApexModelStringWriter<AxTaskSelectionLogic>(false)
+ .writeString(state.getTaskSelectionLogic(), AxTaskSelectionLogic.class));
+ state.setTaskSelectionLogic(new AxTaskSelectionLogic());
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create a policy state output.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param outputName of the state output
+ * @param eventName name of the output event for this state output
+ * @param eventVersion version of the output event for this state output, set to null to use the
+ * latest version
+ * @param nextState for this state to transition to, set to null if this is the last state that
+ * the policy transitions to on this branch
+ * @return result of the operation
+ */
+ public ApexApiResult createPolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName, final String eventName, final String eventVersion, final String nextState) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+ Assertions.argumentNotNull(outputName, "outputName may not be null");
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "Policy concept " + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "State concept " + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), outputName);
+ // There can be multipe state outputs only when the current state is the final state
+ if (nextState != null && !AxReferenceKey.getNullKey().getLocalName().equals(nextState)
+ && state.getStateOutputs().containsKey(refKey.getLocalName())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ "Output concept " + refKey.getId() + ALREADY_EXISTS);
+ }
+
+ final AxEvent event = apexModel.getPolicyModel().getEvents().get(eventName, eventVersion);
+ if (event == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "Event concept " + eventName + ':' + eventVersion + DOES_NOT_EXIST);
+ }
+
+ AxReferenceKey nextStateKey = AxReferenceKey.getNullKey();
+ if (nextState != null && !(AxReferenceKey.getNullKey().getLocalName().equals(nextState))) {
+ if (state.getKey().getLocalName().equals(nextState)) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED,
+ "next state " + nextState + " of a state cannot be the state itself");
+ }
+ nextStateKey = new AxReferenceKey(state.getKey().getParentArtifactKey(), nextState);
+
+ if (!policy.getStateMap().containsKey(nextState)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "Next state concept " + nextStateKey.getId() + DOES_NOT_EXIST);
+ }
+ }
+
+ populateStateOuputInfo(nextState, state, refKey, event, nextStateKey);
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ private void populateStateOuputInfo(final String nextState, final AxState state, final AxReferenceKey refKey,
+ final AxEvent event, AxReferenceKey nextStateKey) {
+ // nextState is null. There could be multiple events coming out of the state
+ if ((nextState == null || AxReferenceKey.getNullKey().getLocalName().equals(nextState))
+ && state.getStateOutputs().containsKey(refKey.getLocalName())) {
+ AxStateOutput existingStateOutput = state.getStateOutputs().get(refKey.getLocalName());
+ if (null == existingStateOutput.getOutgoingEventSet()
+ || existingStateOutput.getOutgoingEventSet().isEmpty()) {
+ Set<AxArtifactKey> eventSet = new TreeSet<>();
+ eventSet.add(existingStateOutput.getOutgoingEvent());
+ existingStateOutput.setOutgoingEventSet(eventSet);
+ }
+ existingStateOutput.getOutgoingEventSet().add(event.getKey());
+ } else {
+ AxStateOutput axStateOutput = new AxStateOutput(refKey, event.getKey(), nextStateKey);
+ Set<AxArtifactKey> eventSet = new TreeSet<>();
+ eventSet.add(axStateOutput.getOutgoingEvent());
+ axStateOutput.setOutgoingEventSet(eventSet);
+ state.getStateOutputs().put(refKey.getLocalName(), axStateOutput);
+ }
+ }
+
+ /**
+ * List policy state outputs.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param outputName of the state output, set to null to list all outputs of the state
+ * @return result of the operation
+ */
+ public ApexApiResult listPolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ if (outputName != null) {
+ final AxStateOutput stateOutput = state.getStateOutputs().get(outputName);
+ if (stateOutput != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput, AxStateOutput.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + state.getKey().getId() + ':' + outputName + DOES_NOT_EXIST);
+ }
+ } else {
+ if (state.getStateOutputs().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no state output concepts exist for state " + state.getKey().getId());
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+
+ for (final AxStateOutput stateOutput : state.getStateOutputs().values()) {
+ result.addMessage(
+ new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput, AxStateOutput.class));
+ }
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a policy state output.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param outputName of the state output, set to null to delete all state outputs
+ * @return result of the operation
+ */
+ public ApexApiResult deletePolicyStateOutput(final String name, final String version, final String stateName,
+ final String outputName) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ if (outputName != null) {
+ final AxStateOutput stateOutput = state.getStateOutputs().get(outputName);
+ if (stateOutput != null) {
+ final ApexApiResult result = new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput, AxStateOutput.class));
+ state.getStateOutputs().remove(outputName);
+ return result;
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + state.getKey().getId() + ':' + outputName + DOES_NOT_EXIST);
+ }
+ } else {
+ if (state.getStateOutputs().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no state output concepts exist for state " + state.getKey().getId());
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+
+ for (final Entry<String, AxStateOutput> stateOutputEntry : state.getStateOutputs().entrySet()) {
+ result.addMessage(new ApexModelStringWriter<AxStateOutput>(false)
+ .writeString(stateOutputEntry.getValue(), AxStateOutput.class));
+ }
+ state.getStateOutputs().clear();
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create policy finalizer logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param finalizerLogicName name of the state finalizer logic
+ * @param logicFlavour the policy finalizer logic flavour for the state, set to null to use the
+ * default task logic flavour
+ * @param logic the source code for the logic of the state
+ * @return result of the operation
+ */
+ public ApexApiResult createPolicyStateFinalizerLogic(final String name, final String version,
+ final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+ Assertions.argumentNotNull(finalizerLogicName, "finalizerlogicName may not be null");
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
+
+ if (state.getStateFinalizerLogicMap().containsKey(refKey.getLocalName())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ CONCEPT + refKey.getId() + ALREADY_EXISTS);
+ }
+
+ state.getStateFinalizerLogicMap().put(finalizerLogicName,
+ new AxStateFinalizerLogic(refKey, logicFlavour, logic));
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update policy finalizer logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param finalizerLogicName name of the state finalizer logic
+ * @param logicFlavour the policy finalizer logic flavour for the state, set to null to not
+ * update
+ * @param logic the source code for the logic of the state, set to null to not update
+ * @return result of the operation
+ */
+ public ApexApiResult updatePolicyStateFinalizerLogic(final String name, final String version,
+ final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+ Assertions.argumentNotNull(finalizerLogicName, "finalizerLogicName may not be null");
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
+ final AxStateFinalizerLogic stateFinalizerLogic =
+ state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
+ if (stateFinalizerLogic == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ STATE_FINALIZER_LOGIC + refKey.getId() + DOES_NOT_EXIST);
+ }
+
+ if (logicFlavour != null) {
+ stateFinalizerLogic.setLogicFlavour(logicFlavour);
+ }
+ if (logic != null) {
+ stateFinalizerLogic.setLogic(logic);
+ }
+
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List policy finalizer logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param finalizerLogicName name of the state finalizer logic
+ * @return result of the operation
+ */
+ public ApexApiResult listPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+ final String finalizerLogicName) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ if (finalizerLogicName != null) {
+ final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
+ final AxStateFinalizerLogic stateFinalizerLogic =
+ state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
+ if (stateFinalizerLogic == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ STATE_FINALIZER_LOGIC + refKey.getId() + DOES_NOT_EXIST);
+ }
+
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxStateFinalizerLogic>(false).writeString(stateFinalizerLogic,
+ AxStateFinalizerLogic.class));
+ } else {
+ if (state.getStateFinalizerLogicMap().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no state finalizer logic defined on state " + state.getKey().getId());
+ }
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxStateFinalizerLogic stateFinalizerLogic : state.getStateFinalizerLogicMap().values()) {
+ result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
+ .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class));
+ }
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete policy finalizer logic for a state.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param finalizerLogicName name of the state finalizer logic
+ * @return result of the operation
+ */
+ public ApexApiResult deletePolicyStateFinalizerLogic(final String name, final String version,
+ final String stateName, final String finalizerLogicName) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ if (finalizerLogicName != null) {
+ final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
+ final AxStateFinalizerLogic stateFinalizerLogic =
+ state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
+ if (stateFinalizerLogic == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ STATE_FINALIZER_LOGIC + refKey.getId() + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
+ .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class));
+ state.getStateFinalizerLogicMap().remove(refKey.getLocalName());
+ return result;
+ } else {
+ if (state.getStateFinalizerLogicMap().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no state finalizer logic defined on state " + state.getKey().getId());
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxStateFinalizerLogic stateFinalizerLogic : state.getStateFinalizerLogicMap().values()) {
+ result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
+ .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class));
+ }
+ state.getStateFinalizerLogicMap().clear();
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create a policy state task reference.
+ *
+ * @param builder builder for the state task reference
+ * @return result of the operation
+ */
+ public ApexApiResult createPolicyStateTaskRef(CreatePolicyStateTaskRef builder) {
+ try {
+ Assertions.argumentNotNull(builder.getStateName(), STATE_NAME_MAY_NOT_BE_NULL);
+ Assertions.argumentNotNull(builder.getOutputName(), "outputName may not be null");
+
+ final AxPolicy policy =
+ apexModel.getPolicyModel().getPolicies().get(builder.getName(), builder.getVersion());
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + builder.getName() + ':' + builder.getVersion() + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(builder.getStateName());
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + builder.getStateName() + DOES_NOT_EXIST);
+ }
+
+ final AxTask task =
+ apexModel.getPolicyModel().getTasks().get(builder.getTaskName(), builder.getTaskVersion());
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + builder.getTaskName() + ':' + builder.getTaskVersion() + DOES_NOT_EXIST);
+ }
+
+ if (state.getTaskReferences().containsKey(task.getKey())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, "task " + task.getKey().getId()
+ + " already has reference with output " + state.getTaskReferences().get(task.getKey()));
+ }
+
+ AxReferenceKey refKey;
+ if (builder.getTaskLocalName() == null) {
+ refKey = new AxReferenceKey(state.getKey(), state.getKey().getParentKeyName());
+ } else {
+ refKey = new AxReferenceKey(state.getKey(), builder.getTaskLocalName());
+ }
+
+ // The reference to the output we're using here
+ final AxReferenceKey outputRefKey = new AxReferenceKey(state.getKey(), builder.getOutputName());
+
+ final AxStateTaskOutputType stateTaskOutputType = AxStateTaskOutputType.valueOf(builder.getOutputType());
+ if (stateTaskOutputType.equals(AxStateTaskOutputType.DIRECT)) {
+ if (!state.getStateOutputs().containsKey(outputRefKey.getLocalName())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "state output concept " + outputRefKey.getId() + DOES_NOT_EXIST);
+ }
+ } else if (stateTaskOutputType.equals(AxStateTaskOutputType.LOGIC)) {
+ if (!state.getStateFinalizerLogicMap().containsKey(outputRefKey.getLocalName())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "state finalizer logic concept " + outputRefKey.getId() + DOES_NOT_EXIST);
+ }
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.FAILED,
+ "output type " + builder.getOutputType() + " invalid");
+ }
+
+ String outputRefName = outputRefKey.getLocalName();
+ // in case of SFL, outgoing event will be same for all state outputs that are part of SFL.So, take any entry
+ if (AxStateTaskOutputType.LOGIC.equals(stateTaskOutputType)) {
+ outputRefName = state.getStateOutputs().keySet().iterator().next();
+ }
+
+ // add input and output events to the task based on state definition
+ if (state.getStateOutputs().containsKey(outputRefName)) {
+ populateIoEventsToTask(state, task, outputRefName);
+ }
+
+ state.getTaskReferences().put(task.getKey(),
+ new AxStateTaskReference(refKey, stateTaskOutputType, outputRefKey));
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ private void populateIoEventsToTask(final AxState state, final AxTask task, final String outputRefName) {
+ AxEvent triggerEvent = apexModel.getPolicyModel().getEvents().get(state.getTrigger());
+ task.setInputEvent(triggerEvent);
+ Map<String, AxEvent> outputEvents = new TreeMap<>();
+ if (state.getNextStateSet().isEmpty()
+ || state.getNextStateSet().contains(AxReferenceKey.getNullKey().getLocalName())) {
+ state.getStateOutputs().get(outputRefName).getOutgoingEventSet().forEach(outgoingEventKey -> outputEvents
+ .put(outgoingEventKey.getName(), apexModel.getPolicyModel().getEvents().get(outgoingEventKey)));
+ } else {
+ AxArtifactKey outgoingEventKey = state.getStateOutputs().get(outputRefName).getOutgoingEvent();
+ outputEvents.put(outgoingEventKey.getName(), apexModel.getPolicyModel().getEvents().get(outgoingEventKey));
+ }
+ task.setOutputEvents(outputEvents);
+ }
+
+ /**
+ * List policy state task references.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param taskName name of the task, set to null to list all task references
+ * @param taskVersion version of the task, set to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult listPolicyStateTaskRef(final String name, final String version, final String stateName,
+ final String taskName, final String taskVersion) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ boolean found = false;
+ final Map<AxArtifactKey, AxStateTaskReference> taskReferences = state.getTaskReferences();
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskReferenceEntry : taskReferences.entrySet()) {
+ final AxArtifactKey key = taskReferenceEntry.getKey();
+ final AxStateTaskReference value = taskReferenceEntry.getValue();
+ if ((taskName != null && !key.getName().equals(taskName))
+ || (taskVersion != null && !key.getVersion().equals(taskVersion))) {
+ continue;
+ }
+
+ found = true;
+ result
+ .addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(key, AxArtifactKey.class));
+ result.addMessage(new ApexModelStringWriter<AxStateTaskReference>(false).writeString(value,
+ AxStateTaskReference.class));
+ }
+ if (found) {
+ return result;
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no task references found for state " + state.getKey().getId());
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a policy state task reference.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param taskName name of the task, set to null to delete all task references
+ * @param taskVersion version of the task, set to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult deletePolicyStateTaskRef(final String name, final String version, final String stateName,
+ final String taskName, final String taskVersion) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ final Set<AxArtifactKey> deleteSet = new TreeSet<>();
+
+ for (final AxArtifactKey taskReferenceKey : state.getTaskReferences().keySet()) {
+ if ((taskName != null && !taskReferenceKey.getName().equals(taskName))
+ || (taskVersion != null && !taskReferenceKey.getVersion().equals(taskVersion))) {
+ continue;
+ }
+ deleteSet.add(taskReferenceKey);
+ }
+ if (deleteSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + taskName + ':' + taskVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getId());
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxArtifactKey keyToDelete : deleteSet) {
+ state.getTaskReferences().remove(keyToDelete);
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyToDelete, AxArtifactKey.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create a policy state context album reference.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param contextAlbumName name of the context album for the context album reference
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult createPolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ final AxContextAlbum contextAlbum =
+ apexModel.getPolicyModel().getAlbums().get(contextAlbumName, contextAlbumVersion);
+ if (contextAlbum == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
+ }
+
+ if (state.getContextAlbumReferences().contains(contextAlbum.getKey())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, "concept album reference for concept "
+ + contextAlbum.getKey().getId() + " already exists in state");
+ }
+
+ state.getContextAlbumReferences().add(contextAlbum.getKey());
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List policy state context album references.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the latest version
+ * @param stateName of the state
+ * @param contextAlbumName name of the context album for the context album reference, set to
+ * null to list all task context album references
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult listPolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ boolean found = false;
+ for (final AxArtifactKey albumKey : state.getContextAlbumReferences()) {
+ if ((contextAlbumName != null && !albumKey.getName().equals(contextAlbumName))
+ || (contextAlbumVersion != null && !albumKey.getVersion().equals(contextAlbumVersion))) {
+ continue;
+ }
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(albumKey, AxArtifactKey.class));
+ found = true;
+ }
+ if (!found) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, CONCEPT + contextAlbumName + ':'
+ + contextAlbumVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getId());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a policy state context album reference.
+ *
+ * @param name name of the policy
+ * @param version version of the policy, set to null to use the default version
+ * @param stateName of the state
+ * @param contextAlbumName name of the context album for the context album reference, set to
+ * null to delete all task context album references
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult deletePolicyStateContextRef(final String name, final String version, final String stateName,
+ final String contextAlbumName, final String contextAlbumVersion) {
+ try {
+ Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+ final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+ if (policy == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxState state = policy.getStateMap().get(stateName);
+ if (state == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
+ }
+
+ final Set<AxArtifactKey> deleteSet = new TreeSet<>();
+
+ for (final AxArtifactKey albumKey : state.getContextAlbumReferences()) {
+
+ if ((contextAlbumName != null && !albumKey.getName().equals(contextAlbumName))
+ || (contextAlbumVersion != null && !albumKey.getVersion().equals(contextAlbumVersion))) {
+
+ continue;
+ }
+ deleteSet.add(albumKey);
+ }
+ if (deleteSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, CONCEPT + contextAlbumName + ':'
+ + contextAlbumVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getId());
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxArtifactKey keyToDelete : deleteSet) {
+ state.getContextAlbumReferences().remove(keyToDelete);
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyToDelete, AxArtifactKey.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/TaskFacade.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/TaskFacade.java
new file mode 100644
index 000000000..6a2ded3e2
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/TaskFacade.java
@@ -0,0 +1,597 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.modelapi.ApexApiResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model for task operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TaskFacade {
+ private static final String CONCEPT = "concept ";
+ private static final String CONCEPT_S = "concept(s) ";
+ private static final String DOES_NOT_EXIST = " does not exist";
+ private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+ private static final String ALREADY_EXISTS = " already exists";
+
+ // Apex model we're working towards
+ private final ApexModel apexModel;
+
+ // Properties to use for the model
+ private final Properties apexProperties;
+
+ // Facade classes for working towards the real Apex model
+ private final KeyInformationFacade keyInformationFacade;
+
+ /**
+ * Constructor that creates a task facade for the Apex Model API.
+ *
+ * @param apexModel the apex model
+ * @param apexProperties Properties for the model
+ */
+ public TaskFacade(final ApexModel apexModel, final Properties apexProperties) {
+ this.apexModel = apexModel;
+ this.apexProperties = apexProperties;
+
+ keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties);
+ }
+
+ /**
+ * Create a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the default version
+ * @param uuid task UUID, set to null to generate a UUID
+ * @param description task description, set to null to generate a description
+ * @return result of the operation
+ */
+ public ApexApiResult createTask(final String name, final String version, final String uuid,
+ final String description) {
+ try {
+ final AxArtifactKey key = new AxArtifactKey();
+ key.setName(name);
+ if (version != null) {
+ key.setVersion(version);
+ } else {
+ key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+ }
+
+ if (apexModel.getPolicyModel().getTasks().getTaskMap().containsKey(key)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, CONCEPT + key.getId() + ALREADY_EXISTS);
+ }
+
+ apexModel.getPolicyModel().getTasks().getTaskMap().put(key, new AxTask(key));
+
+ if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } else {
+ return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param uuid task UUID, set to null to not update
+ * @param description task description, set to null to not update
+ * @return result of the operation
+ */
+ public ApexApiResult updateTask(final String name, final String version, final String uuid,
+ final String description) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List tasks.
+ *
+ * @param name name of the task, set to null to list all
+ * @param version starting version of the task, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult listTask(final String name, final String version) {
+ try {
+ final Set<AxTask> taskSet = apexModel.getPolicyModel().getTasks().getAll(name, version);
+ if (name != null && taskSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxTask task : taskSet) {
+ result.addMessage(new ApexModelStringWriter<AxTask>(false).writeString(task, AxTask.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult deleteTask(final String name, final String version) {
+ try {
+ if (version != null) {
+ final AxArtifactKey key = new AxArtifactKey(name, version);
+ final AxTask removedTask = apexModel.getPolicyModel().getTasks().getTaskMap().remove(key);
+ if (removedTask != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxTask>(false).writeString(removedTask, AxTask.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + key.getId() + DOES_NOT_EXIST);
+ }
+ }
+
+ final Set<AxTask> taskSet = apexModel.getPolicyModel().getTasks().getAll(name, version);
+ if (taskSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxTask task : taskSet) {
+ result.addMessage(new ApexModelStringWriter<AxTask>(false).writeString(task, AxTask.class));
+ apexModel.getPolicyModel().getTasks().getTaskMap().remove(task.getKey());
+ keyInformationFacade.deleteKeyInformation(name, version);
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Validate tasks.
+ *
+ * @param name name of the task, set to null to list all
+ * @param version starting version of the task, set to null to list all versions
+ * @return result of the operation
+ */
+ public ApexApiResult validateTask(final String name, final String version) {
+ try {
+ final Set<AxTask> taskSet = apexModel.getPolicyModel().getTasks().getAll(name, version);
+ if (taskSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxTask task : taskSet) {
+ final AxValidationResult validationResult = task.validate(new AxValidationResult());
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(task.getKey(), AxArtifactKey.class));
+ result.addMessage(validationResult.toString());
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create logic for a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param logicFlavour the task logic flavour for the task, set to null to use the default task
+ * logic flavour
+ * @param logic the source code for the logic of the task
+ * @return result of the operation
+ */
+ public ApexApiResult createTaskLogic(final String name, final String version, final String logicFlavour,
+ final String logic) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ // There is only one logic item associated with a task so we use a hard coded logic name
+ final AxReferenceKey refKey = new AxReferenceKey(task.getKey(), "TaskLogic");
+
+ if (!task.getTaskLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ CONCEPT + refKey.getId() + ALREADY_EXISTS);
+ }
+
+ task.setTaskLogic(new AxTaskLogic(refKey, logicFlavour, logic));
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Update logic for a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param logicFlavour the task logic flavour for the task, set to null to not update
+ * @param logic the source code for the logic of the task, set to null to not update
+ * @return result of the operation
+ */
+ public ApexApiResult updateTaskLogic(final String name, final String version, final String logicFlavour,
+ final String logic) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ if (task.getTaskLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + task.getTaskLogic().getKey().getId() + DOES_NOT_EXIST);
+ }
+
+ final AxTaskLogic taskLogic = task.getTaskLogic();
+ if (logicFlavour != null) {
+ taskLogic.setLogicFlavour(logicFlavour);
+ }
+ if (logic != null) {
+ taskLogic.setLogic(logic);
+ }
+
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List task logic.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to list the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult listTaskLogic(final String name, final String version) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxTaskLogic>(false).writeString(task.getTaskLogic(), AxTaskLogic.class));
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete logic for a task.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult deleteTaskLogic(final String name, final String version) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ if (task.getTaskLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + task.getTaskLogic().getKey().getId() + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ result.addMessage(
+ new ApexModelStringWriter<AxTaskLogic>(false).writeString(task.getTaskLogic(), AxTaskLogic.class));
+ task.setTaskLogic(new AxTaskLogic());
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create a task parameter.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param parName of the parameter
+ * @param defaultValue of the parameter
+ * @return result of the operation
+ */
+ public ApexApiResult createTaskParameter(final String name, final String version, final String parName,
+ final String defaultValue) {
+ try {
+ Assertions.argumentNotNull(parName, "parName may not be null");
+
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxReferenceKey refKey = new AxReferenceKey(task.getKey(), parName);
+
+ if (task.getTaskParameters().containsKey(refKey.getLocalName())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ CONCEPT + refKey.getId() + ALREADY_EXISTS);
+ }
+
+ task.getTaskParameters().put(refKey.getLocalName(), new AxTaskParameter(refKey, defaultValue));
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List task parameters.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param parName name of the parameter, set to null to list all parameters of the task
+ * @return result of the operation
+ */
+ public ApexApiResult listTaskParameter(final String name, final String version, final String parName) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ if (parName != null) {
+ final AxTaskParameter taskParameter = task.getTaskParameters().get(parName);
+ if (taskParameter != null) {
+ return new ApexApiResult(ApexApiResult.Result.SUCCESS,
+ new ApexModelStringWriter<AxTaskParameter>(false).writeString(taskParameter,
+ AxTaskParameter.class));
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + ':' + taskParameter + DOES_NOT_EXIST);
+ }
+ } else {
+ if (task.getTaskParameters().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no task parameters defined on task " + task.getKey().getId());
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxTaskParameter parameter : task.getTaskParameters().values()) {
+ result.addMessage(new ApexModelStringWriter<AxTaskParameter>(false).writeString(parameter,
+ AxTaskParameter.class));
+ }
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a task parameter.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param parName of the parameter, set to null to delete all task parameters
+ * @return result of the operation
+ */
+ public ApexApiResult deleteTaskParameter(final String name, final String version, final String parName) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ if (parName != null) {
+ if (task.getTaskParameters().containsKey(parName)) {
+ result.addMessage(new ApexModelStringWriter<AxTaskParameter>(false)
+ .writeString(task.getTaskParameters().get(parName), AxTaskParameter.class));
+ task.getTaskParameters().remove(parName);
+ return result;
+ } else {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + ':' + parName + DOES_NOT_EXIST);
+ }
+ } else {
+ if (task.getTaskParameters().size() == 0) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ "no task parameters defined on task " + task.getKey().getId());
+ }
+
+ for (final AxTaskParameter parameter : task.getTaskParameters().values()) {
+ result.addMessage(new ApexModelStringWriter<AxTaskParameter>(false).writeString(parameter,
+ AxTaskParameter.class));
+ }
+ task.getTaskParameters().clear();
+ return result;
+ }
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Create a task context album reference.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param contextAlbumName name of the context album for the context album reference
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult createTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final AxContextAlbum contextAlbum =
+ apexModel.getPolicyModel().getAlbums().get(contextAlbumName, contextAlbumVersion);
+ if (contextAlbum == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
+ }
+
+ if (task.getContextAlbumReferences().contains(contextAlbum.getKey())) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
+ "context album reference for concept " + contextAlbum.getKey().getId() + " already exists in task");
+ }
+
+ task.getContextAlbumReferences().add(contextAlbum.getKey());
+ return new ApexApiResult();
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * List task context album references.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param contextAlbumName name of the context album for the context album reference, set to
+ * null to list all task context album references
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult listTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final ApexApiResult result = new ApexApiResult();
+ boolean found = false;
+ for (final AxArtifactKey albumKey : task.getContextAlbumReferences()) {
+ if ((contextAlbumName != null && !albumKey.getName().equals(contextAlbumName))
+ || (contextAlbumVersion != null && !albumKey.getVersion().equals(contextAlbumVersion))) {
+ continue;
+ }
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(albumKey, AxArtifactKey.class));
+ found = true;
+ }
+ if (!found) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+
+ /**
+ * Delete a task context album reference.
+ *
+ * @param name name of the task
+ * @param version version of the task, set to null to use the latest version
+ * @param contextAlbumName name of the context album for the context album reference, set to
+ * null to delete all task context album references
+ * @param contextAlbumVersion version of the context album for the context album reference, set
+ * to null to use the latest version
+ * @return result of the operation
+ */
+ public ApexApiResult deleteTaskContextRef(final String name, final String version, final String contextAlbumName,
+ final String contextAlbumVersion) {
+ try {
+ final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+ if (task == null) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+ }
+
+ final Set<AxArtifactKey> deleteSet = new TreeSet<>();
+
+ for (final AxArtifactKey albumKey : task.getContextAlbumReferences()) {
+ if ((contextAlbumName != null && !albumKey.getName().equals(contextAlbumName))
+ || (contextAlbumVersion != null && !albumKey.getVersion().equals(contextAlbumVersion))) {
+ continue;
+ }
+ deleteSet.add(albumKey);
+ }
+
+ if (deleteSet.isEmpty()) {
+ return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
+ CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
+ }
+ final ApexApiResult result = new ApexApiResult();
+ for (final AxArtifactKey keyToDelete : deleteSet) {
+ task.getContextAlbumReferences().remove(keyToDelete);
+ result.addMessage(
+ new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyToDelete, AxArtifactKey.class));
+ }
+ return result;
+ } catch (final Exception e) {
+ return new ApexApiResult(ApexApiResult.Result.FAILED, e);
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/package-info.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/package-info.java
new file mode 100644
index 000000000..f31542044
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/impl/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Provides an implementation of the APEX Model API that holds an APEX model and manipulates its
+ * various parts in response to operations called over the Model API.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.modelapi.impl;
diff --git a/model/src/main/java/org/onap/policy/apex/model/modelapi/package-info.java b/model/src/main/java/org/onap/policy/apex/model/modelapi/package-info.java
new file mode 100644
index 000000000..97e8db4ea
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/modelapi/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Provides an API to APEX models so that they can be manipulated over a common interface by CLI and
+ * GUI based editors and other development tools.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.modelapi;
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogic.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogic.java
new file mode 100644
index 000000000..0564d5854
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogic.java
@@ -0,0 +1,355 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,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.onap.policy.apex.model.policymodel.concepts;
+
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class holds Logic for executing a task or task selection on an Apex policy state. The flavour of the logic
+ * describes the type of logic being used and it may be a language identifier such as "Javascript" or "Jython". The
+ * logic itself is held as a string. The {@link AxLogic} instance is used by the Apex engine to start an executor with
+ * the required flavour. Once the executor is started, the Apex engine passes the logic to the executor and the executor
+ * executes it. In the Apex engine, executors are deployed as plugins. Apex also provides the executor with run-time
+ * context, which makes context such as input fields, output fields, and context albums available to the task at
+ * runtime.
+ *
+ * <p>Validation checks that the logic key is valid, that the logic flavour is defined and is valid when checked against
+ * the {@code LOGIC_FLAVOUR_REGEXP} regular expression, and that the specified logic string is not null or blank.
+ */
+public class AxLogic extends AxConcept {
+ private static final long serialVersionUID = -4260562004005697328L;
+
+ private static final String WHITESPACE_REGEXP = "\\s+$";
+
+ private static final String LOGIC_FLAVOUR_TOKEN = "logicFlavour";
+ private static final String KEY_NULL_MESSAGE = "key may not be null";
+ private static final String LOGIC_FLAVOUR_NULL_MESSAGE = "logicFlavour may not be null";
+ private static final String LOGIC_NULL_MESSAGE = "logic may not be null";
+
+ /** Regular expression that specifies the allowed characters in logic flavour tokens. */
+ public static final String LOGIC_FLAVOUR_REGEXP = "[A-Za-z0-9\\-_]+";
+
+ /** When logic flavour is undefined, it has this value. */
+ public static final String LOGIC_FLAVOUR_UNDEFINED = "UNDEFINED";
+
+ /** The maximum permissible size of a logic definition. */
+ public static final int MAX_LOGIC_SIZE = 32672; // The maximum size supported by Apache Derby
+
+ private AxReferenceKey key;
+ private String logicFlavour;
+ private String logic;
+
+ /**
+ * The Default Constructor creates a logic instance with a null key, undefined logic flavour and a null logic
+ * string.
+ */
+ public AxLogic() {
+ this(new AxReferenceKey());
+ logicFlavour = LOGIC_FLAVOUR_UNDEFINED;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxLogic(final AxLogic copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a logic instance with the given reference key, undefined logic flavour and a null
+ * logic string.
+ *
+ * @param key the reference key of the logic
+ */
+ public AxLogic(final AxReferenceKey key) {
+ this(key, LOGIC_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents key and the logic
+ * local name and all of its fields defined.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final String logic) {
+ this(new AxReferenceKey(parentKey, logicName), logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and all of its fields defined.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxLogic(final AxReferenceKey key, final String logicFlavour, final String logic) {
+ super();
+ Assertions.argumentNotNull(key, KEY_NULL_MESSAGE);
+ Assertions.argumentNotNull(logicFlavour, LOGIC_FLAVOUR_NULL_MESSAGE);
+ Assertions.argumentNotNull(logic, LOGIC_NULL_MESSAGE);
+
+ this.key = key;
+ this.logicFlavour = Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ this.logic = logic.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and logic flavour, the logic is provided
+ * by the given logic reader instance.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxLogic(final AxReferenceKey key, final String logicFlavour, final AxLogicReader logicReader) {
+ super();
+ Assertions.argumentNotNull(key, KEY_NULL_MESSAGE);
+ Assertions.argumentNotNull(logicFlavour, LOGIC_FLAVOUR_NULL_MESSAGE);
+ Assertions.argumentNotNull(logicReader, "logicReader may not be null");
+
+ this.key = key;
+ this.logicFlavour = Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ logic = logicReader.readLogic(this);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return key.getKeys();
+ }
+
+ /**
+ * Sets the key.
+ *
+ * @param key the key
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, KEY_NULL_MESSAGE);
+ this.key = key;
+ }
+
+ /**
+ * Gets the logic flavour.
+ *
+ * @return the logic flavour
+ */
+ public String getLogicFlavour() {
+ return logicFlavour;
+ }
+
+ /**
+ * Sets the logic flavour.
+ *
+ * @param logicFlavour the logic flavour
+ */
+ public void setLogicFlavour(final String logicFlavour) {
+ this.logicFlavour = Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ }
+
+ /**
+ * Gets the logic.
+ *
+ * @return the logic
+ */
+ public String getLogic() {
+ return logic;
+ }
+
+ /**
+ * Sets the logic.
+ *
+ * @param logic the logic
+ */
+ public void setLogic(final String logic) {
+ Assertions.argumentNotNull(logic, LOGIC_NULL_MESSAGE);
+ this.logic = logic.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (logicFlavour.replaceAll(WHITESPACE_REGEXP, "").length() == 0
+ || logicFlavour.equals(LOGIC_FLAVOUR_UNDEFINED)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "logic flavour is not defined"));
+ }
+
+ String flavourValidationString = Assertions.getStringParameterValidationMessage(LOGIC_FLAVOUR_TOKEN,
+ logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ if (flavourValidationString != null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "logic flavour invalid-" + flavourValidationString));
+ }
+
+ if (logic.replaceAll(WHITESPACE_REGEXP, "").length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "no logic specified, logic may not be blank"));
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ if (key != null) {
+ key.clean();
+ }
+ logicFlavour = Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ logic = logic.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",logicFlavour=");
+ builder.append(logicFlavour);
+ builder.append(",logic=");
+ builder.append(logic);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxLogic.class);
+
+ final AxLogic copy = ((AxLogic) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setLogicFlavour(logicFlavour);
+ copy.setLogic(logic);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + logicFlavour.hashCode();
+ result = prime * result + logic.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxLogic other = (AxLogic) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!logicFlavour.equals(other.logicFlavour)) {
+ return false;
+ }
+ return logic.equals(other.logic);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxLogic other = (AxLogic) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!logicFlavour.equals(other.logicFlavour)) {
+ return logicFlavour.compareTo(other.logicFlavour);
+ }
+ return logic.compareTo(other.logic);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogicReader.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogicReader.java
new file mode 100644
index 000000000..7532f9f34
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogicReader.java
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+/**
+ * This interface is used to provide logic to a {@link AxLogic} instance. Implementations usually
+ * store logic on disk in a structure similar to Java package naming conventions. The logic package
+ * gives the package path, a directory where a set of logic is defined. Default logic is logic that
+ * can be used as dummy logic in tasks or states that are filler tasks or states. The actual logic
+ * is returned by the {@code readLogic()} method. The interface is used mainly by unit test classes
+ * that generate test logic.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface AxLogicReader {
+
+ /**
+ * Get the logic package path.
+ *
+ * @return the logic package path
+ */
+ String getLogicPackage();
+
+ /**
+ * Set the logic package path.
+ *
+ * @param logicPackage the name of the package that contains the logic for this logic reader
+ * @return the logic reader on which this method was called, used for daisy chaining
+ * configuration
+ */
+ AxLogicReader setLogicPackage(final String logicPackage);
+
+ /**
+ * Get the default logic name.
+ *
+ * @return the default logic name
+ */
+ String getDefaultLogic();
+
+ /**
+ * Set the default logic name.
+ *
+ * @param defaultLogic the default logic name
+ * @return the logic reader on which this method was called, used for daisy chaining
+ * configuration
+ */
+ AxLogicReader setDefaultLogic(final String defaultLogic);
+
+ /**
+ * Read the logic for an AxLogic object.
+ *
+ * @param axLogic the AxLogic object
+ * @return the logic as a string
+ */
+ String readLogic(final AxLogic axLogic);
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicies.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicies.java
new file mode 100644
index 000000000..bb30f46cf
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicies.java
@@ -0,0 +1,360 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,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.onap.policy.apex.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is a policy container and holds a map of the policies for an entire Apex model. All Apex models that use
+ * policies must have an {@link AxPolicies} field. The {@link AxPolicies} class implements the helper methods of the
+ * {@link AxConceptGetter} interface to allow {@link AxPolicy} instances to be retrieved by calling methods directly on
+ * this class without referencing the contained map.
+ *
+ * <p>Validation checks that the container key is not null. An error is issued if no policies are defined in the
+ * container. Each policy entry is checked to ensure that its key and value are not null and that the key matches the
+ * key in the map value. Each policy entry is then validated individually.
+ */
+public class AxPolicies extends AxConcept implements AxConceptGetter<AxPolicy> {
+ private static final long serialVersionUID = 4290442590545820316L;
+
+ private AxArtifactKey key;
+ private Map<AxArtifactKey, AxPolicy> policyMap;
+
+ /**
+ * The Default Constructor creates a {@link AxPolicies} object with a null artifact key and creates an empty event
+ * map.
+ */
+ public AxPolicies() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxPolicies} object with the given artifact key and creates an empty event
+ * map.
+ *
+ * @param key the key
+ */
+ public AxPolicies(final AxArtifactKey key) {
+ this(key, new TreeMap<>());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxPolicies(final AxPolicies copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * This Constructor creates a policy container with all of its fields defined.
+ *
+ * @param key the policy container key
+ * @param policyMap the policies to be stored in the policy container
+ */
+ public AxPolicies(final AxArtifactKey key, final Map<AxArtifactKey, AxPolicy> policyMap) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(policyMap, "policyMap may not be null");
+
+ this.key = key;
+ this.policyMap = new TreeMap<>();
+ this.policyMap.putAll(policyMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ for (final AxPolicy policy : policyMap.values()) {
+ keyList.addAll(policy.getKeys());
+ }
+
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void buildReferences() {
+ policyMap.entrySet().stream().forEach(policyEntry -> {
+ policyEntry.getValue().setKey(policyEntry.getKey());
+ policyEntry.getValue().buildReferences();
+ }
+ );
+ }
+
+ /**
+ * Sets the key of the policy container.
+ *
+ * @param key the policy container key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the policy map containing all policies in the policy container.
+ *
+ * @return the policy map with all the policies in the container
+ */
+ public Map<AxArtifactKey, AxPolicy> getPolicyMap() {
+ return policyMap;
+ }
+
+ /**
+ * Sets the policy map containing all policies in the policy container.
+ *
+ * @param policyMap the policy map with all the policies to be put in the container
+ */
+ public void setPolicyMap(final Map<AxArtifactKey, AxPolicy> policyMap) {
+ Assertions.argumentNotNull(policyMap, "policyMap may not be null");
+ this.policyMap = new TreeMap<>();
+ this.policyMap.putAll(policyMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (policyMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "policyMap may not be empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxPolicy> policyEntry : policyMap.entrySet()) {
+ final AxArtifactKey entryKey = policyEntry.getKey();
+ if (entryKey.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on policy entry " + entryKey + " may not be the null key"));
+ } else if (policyEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on policy entry " + entryKey + " may not be null"));
+ } else {
+ validate(result, policyEntry, entryKey);
+ result = policyEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void validate(final AxValidationResult result, final Entry<AxArtifactKey, AxPolicy> policyEntry,
+ final AxArtifactKey entryKey) {
+ if (!entryKey.equals(policyEntry.getValue().getKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on policy entry key " + entryKey + " does not equal policy value key "
+ + policyEntry.getValue().getKey()));
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxPolicy> policyEntry : policyMap.entrySet()) {
+ policyEntry.getKey().clean();
+ policyEntry.getValue().clean();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",policyMap=");
+ builder.append(policyMap);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxPolicies.class);
+
+ final AxPolicies copy = ((AxPolicies) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+
+ final Map<AxArtifactKey, AxPolicy> newPolicyMap = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxPolicy> policyMapEntry : policyMap.entrySet()) {
+ newPolicyMap.put(new AxArtifactKey(policyMapEntry.getKey()), new AxPolicy(policyMapEntry.getValue()));
+ }
+ copy.setPolicyMap(newPolicyMap);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + policyMap.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxPolicies other = (AxPolicies) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return policyMap.equals(other.policyMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxPolicies other = (AxPolicies) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!policyMap.equals(other.policyMap)) {
+ return (policyMap.hashCode() - other.policyMap.hashCode());
+ }
+
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxPolicy get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxPolicy get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxPolicy get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxPolicy> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).getAll(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxPolicy> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicy.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicy.java
new file mode 100644
index 000000000..a47afe4d6
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicy.java
@@ -0,0 +1,508 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,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.onap.policy.apex.model.policymodel.concepts;
+
+import com.google.gson.annotations.SerializedName;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class holds the definition of an Apex policy. A policy is made up of a tree of states, each represented by an
+ * {@link AxState} instance. The states of a policy are held in a map in the policy. The state tree is built up at
+ * policy design time by a policy editor and each state is connected to its next state by an {@link AxStateOutput}
+ * instance.
+ *
+ * <p>Execution of a policy is triggered by an event. A policy starts execution from its first state so the trigger
+ * event for the first sate is the trigger event for the entire policy. Execution from that first state can continue to
+ * one or more subsequent states and so on down branches of states. The state output of the final state in a branch has
+ * no next state, indicating the end of execution of that branch. Therefore, the set of output events from final states
+ * in the policy are the possible set of output events on the policy. A state may only be used once in the state tree of
+ * a policy and recursive execution of states in the same execution branch is not allowed, so the same state may not
+ * execute more than once on a single execution of a policy.
+ *
+ * <p>The template of a policy is a string that can be used by policy editors to store meta information on the policy
+ * that can be used at design time. The policy template string is not used during policy execution.
+ *
+ * <p>During validation of a policy, the validation checks listed below are executed:
+ * <ol>
+ * <li>The policy key must not
+ * be a null key
+ * <li>The policy key must be valid
+ * <li>If the policy template is not set, an observation is issued
+ * <li>At
+ * least one state must be defined
+ * <li>Keys and values must all be defined, that is not null
+ * <li>The key on each entry
+ * in the state map must match the key in the entry's value
+ * <li>The parent key of each state in the state map of a
+ * policy must be the key of that policy
+ * <li>Each state must itself be valid, see validation in {@link AxState}
+ * <li>The
+ * next state of the state output of each state must be defined as a state in the policy
+ * <li>The first state of a policy
+ * must be set
+ * <li>The first state of a policy must be defined in the policy
+ * <li>If a state is defined but is not used
+ * in a policy,a warning is issued
+ * <li>The state tree of the policy must be valid, see validation in {@link AxStateTree}
+ * </ol>
+ */
+public class AxPolicy extends AxConcept {
+ private static final long serialVersionUID = -1775614096390365941L;
+
+ // Logger for this class
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(AxPolicy.class);
+
+ @SerializedName("policyKey")
+ private AxArtifactKey key;
+ private String template;
+
+ @SerializedName("state")
+ private Map<String, AxState> stateMap;
+ private String firstState;
+
+ /**
+ * The Default Constructor creates a policy instance with a null key, a blank template and undefined first state.
+ */
+ public AxPolicy() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxPolicy(final AxPolicy copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a policy instance with the given key, a blank template and undefined first state.
+ *
+ * @param key the key of the policy
+ */
+ public AxPolicy(final AxArtifactKey key) {
+ this(key,
+ "",
+ new TreeMap<>(),
+ "");
+ }
+
+ /**
+ * This Constructor creates a policy with the given key and all its fields defined.
+ *
+ * @param key the key of the policy
+ * @param template the policy template for policy editor metadata
+ * @param stateMap the state map containing the states of the policy
+ * @param firstState the first state that will execute on this policy
+ */
+ public AxPolicy(final AxArtifactKey key, final String template, final Map<String, AxState> stateMap,
+ final String firstState) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(template, "template may not be null");
+ Assertions.argumentNotNull(stateMap, "stateMap may not be null");
+ Assertions.argumentNotNull(firstState, "firstState may not be null");
+
+ this.key = key;
+ this.template = template;
+ this.stateMap = stateMap;
+ this.firstState = firstState;
+ }
+
+ /**
+ * Gets a tree that holds all the possible execution paths for this policy. This method may be used for verification
+ * of policies, to find the branches of policy execution and the final states of policies.
+ *
+ * @return the state tree of the policy, a tree representing the execution branches of the policy
+ */
+ public AxStateTree getStateTree() {
+ return new AxStateTree(this, stateMap.get(firstState), null);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ for (final AxState state : stateMap.values()) {
+ keyList.addAll(state.getKeys());
+ }
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void buildReferences() {
+ stateMap.entrySet().stream().forEach(stateEntry -> {
+ if (!stateEntry.getValue().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ stateEntry.getValue().getKey().setParentArtifactKey(key);
+ }
+ stateEntry.getValue().buildReferences();
+ }
+ );
+ }
+
+ /**
+ * Sets the key of the policy.
+ *
+ * @param key the key of the policy
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the policy template for policy editor metadata.
+ *
+ * @return the policy template for policy editor metadata
+ */
+ public String getTemplate() {
+ return template;
+ }
+
+ /**
+ * Sets the policy template for policy editor metadata.
+ *
+ * @param template the policy template for policy editor metadata
+ */
+ public void setTemplate(final String template) {
+ Assertions.argumentNotNull(template, "template may not be null");
+ this.template = template;
+ }
+
+ /**
+ * Gets a map containing the states of the policy.
+ *
+ * @return the map of states in the policy
+ */
+ public Map<String, AxState> getStateMap() {
+ return stateMap;
+ }
+
+ /**
+ * Sets a map containing the states of the policy.
+ *
+ * @param stateMap a map of states in the policy
+ */
+ public void setStateMap(final Map<String, AxState> stateMap) {
+ Assertions.argumentNotNull(stateMap, "stateMap may not be null");
+ this.stateMap = stateMap;
+ }
+
+ /**
+ * Gets the first state of the policy.
+ *
+ * @return the first state of the policy
+ */
+ public String getFirstState() {
+ return firstState;
+ }
+
+ /**
+ * Sets the first state of the policy.
+ *
+ * @param firstState the first state of the policy
+ */
+ public void setFirstState(final String firstState) {
+ Assertions.argumentNotNull(firstState, "firstState may not be null");
+ this.firstState = firstState;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (template.trim().length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "a policy template has not been specified"));
+ }
+
+ if (stateMap.size() == 0) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateMap may not be empty"));
+ } else {
+ for (final Entry<String, AxState> stateEntry : stateMap.entrySet()) {
+ result = validateStateEntry(stateEntry, result);
+ }
+ }
+
+ // Validation continues from this point only if all validation checks this far have been
+ // passed
+ if (!result.isOk()) {
+ return result;
+ }
+
+ // We only check the unused states on models validated this far
+ if (firstState.trim().length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "no first state specified, first state may not be blank"));
+ } else {
+ if (!stateMap.containsKey(firstState)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "first state not found in stateMap"));
+ } else {
+ validateStateTree(result);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate a state entry.
+ *
+ * @param stateEntry the state entry to validate
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult validateStateEntry(final Entry<String, AxState> stateEntry, AxValidationResult
+ result) {
+ if (stateEntry.getKey() == null || stateEntry.getKey().equals(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on state entry key " + stateEntry.getKey() + " may not be the null key"));
+ return result;
+ }
+
+ if (stateEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on state entry value " + stateEntry.getKey() + " may not be null"));
+ return result;
+ }
+
+ if (!stateEntry.getKey().equals(stateEntry.getValue().getKey().getLocalName())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on state entry key " + stateEntry.getKey() + " does not equal state entry value local name "
+ + stateEntry.getValue().getKey().getLocalName()));
+ }
+
+ if (!stateEntry.getValue().getKey().getParentArtifactKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent key on state entry key " + stateEntry.getValue().getKey() + " does not equal policy key"));
+ }
+
+ result = stateEntry.getValue().validate(result);
+
+ for (final AxStateOutput stateOutput : stateEntry.getValue().getStateOutputs().values()) {
+ if (!stateOutput.getNextState().equals(AxReferenceKey.getNullKey())
+ && !stateMap.containsKey(stateOutput.getNextState().getLocalName())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, " nextState of state "
+ + stateEntry.getKey() + " not found in StateMap: " + stateOutput.getNextState().getId()));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate a state tree to ensure there are no circular references in it.
+ *
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult validateStateTree(AxValidationResult result) {
+ try {
+ // Constructor validates policy state tree
+ AxStateTree policyStateTree = getStateTree();
+
+ // Check for unused states
+ final Set<AxState> referencedStateSet = policyStateTree.getReferencedStateSet();
+ final Set<AxState> unreferencedStateSet = new TreeSet<>(stateMap.values());
+ unreferencedStateSet.removeAll(referencedStateSet);
+
+ for (final AxState unreferencedState : unreferencedStateSet) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.WARNING,
+ "state " + unreferencedState.getKey() + " is not referenced in the policy execution tree"));
+ }
+ } catch (PolicyRuntimeException pre) {
+ AxValidationMessage validationMessage = new AxValidationMessage(key, this.getClass(),
+ ValidationResult.WARNING, "state tree in policy is invalid");
+ LOGGER.trace(validationMessage.getMessage(), pre);
+ result.addValidationMessage(validationMessage);
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ firstState = firstState.trim();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",template=");
+ builder.append(template);
+ builder.append(",stateMap=");
+ builder.append(stateMap);
+ builder.append(",firstState=");
+ builder.append(firstState);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxPolicy.class);
+
+ final AxPolicy copy = ((AxPolicy) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setTemplate(template);
+
+ final Map<String, AxState> newStateMap = new TreeMap<>();
+ for (final Entry<String, AxState> stateMapEntry : stateMap.entrySet()) {
+ newStateMap.put(stateMapEntry.getKey(), new AxState(stateMapEntry.getValue()));
+ }
+ copy.setStateMap(newStateMap);
+
+ copy.setFirstState(firstState);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + template.hashCode();
+ result = prime * result + stateMap.hashCode();
+ result = prime * result + firstState.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxPolicy other = (AxPolicy) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!template.equals(other.template)) {
+ return false;
+ }
+ if (!stateMap.equals(other.stateMap)) {
+ return false;
+ }
+ return firstState.equals(other.firstState);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxPolicy other = (AxPolicy) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!template.equals(other.template)) {
+ return template.compareTo(other.template);
+ }
+ if (!stateMap.equals(other.stateMap)) {
+ return (stateMap.hashCode() - other.stateMap.hashCode());
+ }
+ return firstState.compareTo(other.firstState);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java
new file mode 100644
index 000000000..e119536fb
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java
@@ -0,0 +1,661 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map.Entry;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * A container class for an Apex policy model. This class is a container class that allows an Apex
+ * model to be constructed that contains definitions of all the context, event, and policy concepts
+ * required to run policies in Apex. The model contains schema definitions, definitions of events
+ * and context albums that use those schemas, definitions of tasks for policies and definitions of
+ * the policies themselves.
+ *
+ * <p>An Apex policy model is an important artifact in Apex. At editing time, an Apex editor creates
+ * and edits a policy model and a policy model is loaded into and is executed by an Apex engine.
+ * Therefore, an Apex model and the set of policies that it holds is the way that the policy domain
+ * that an Apex engine or a group of Apex engines executes across is expressed, both at design time
+ * and run time. The Apex deployment system is responsible for deploying Apex models to and the
+ * context they need the appropriate engines for execution.
+ *
+ * <p>Model registration is carried out by calling the {@code register()} method, which registers the
+ * policy model and all its constituent containers with the model service. The containers for
+ * context schemas, events, context albums, tasks, policies, and key information are all registered.
+ *
+ * <p>Once a policy model is composed, the overall structure of the policy model and all its references
+ * can be validated. During validation of a policy model, the validation checks listed below are
+ * executed:
+ * <ol>
+ * <li>The policy model is validated as an Apex model, which validates the existence, correctness,
+ * and duplication of all keys in the model as well as validating the key information of the keys,
+ * see validation in {@link AxModel}
+ * <li>The schemas in the model must be valid, see validation in {@link AxContextSchemas}
+ * <li>The context albums in the model must be valid, see validation in {@link AxContextAlbums}
+ * <li>The tasks in the model must be valid, see validation in {@link AxTasks}
+ * <li>The policies in the model must be valid, see validation in {@link AxPolicies}
+ * <li>The events in the model must be valid, see validation in {@link AxEvents}
+ * <li>The context schemas referred to in each field in every event must exist
+ * <li>The context schemas referred to in every context album must exist
+ * <li>The context schemas referred to in every task input field and output field must exist
+ * <li>The context albums referred to in every task must exist
+ * <li>The context albums referred to in every state must exist
+ * <li>The trigger event referred to in every state must exist
+ * <li>The default task referred to in every state must exist
+ * <li>In a state, an event that triggers a task must contain all the input fields required by that
+ * task
+ * <li>In a state, an event that is emitted by a task must contain all the output fields produced by
+ * that task
+ * <li>All tasks referred to by a state must exist
+ * <li>All events referred to on direct state outputs must exist
+ * </ol>
+ */
+public class AxPolicyModel extends AxModel {
+ // @formatter:off
+ private static final String SCHEMAS_TOKEN = "_Schemas";
+ private static final String KEY_INFO_TOKEN = "_KeyInfo";
+ private static final String EVENTS_TOKEN = "_Events";
+ private static final String ALBUMS_TOKEN = "_Albums";
+ private static final String TASKS_TOKEN = "_Tasks";
+ private static final String POLICIESS_TOKEN = "_Policies";
+
+ private static final String DOES_NOT_EXIST = " does not exist";
+
+ private static final long serialVersionUID = 8800599637708309945L;
+
+ private AxPolicies policies;
+ private AxTasks tasks;
+ private AxEvents events;
+ private AxContextAlbums albums;
+ private AxContextSchemas schemas;
+
+ /**
+ * The Default Constructor creates a policy model with a null key and empty containers for
+ * schemas, key information, events, context albums, tasks and policies.
+ */
+ public AxPolicyModel() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxPolicyModel(final AxPolicyModel copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a policy model with the given key and empty containers for
+ * schemas, key information, events, context albums, tasks and policies.
+ *
+ * @param key the key
+ */
+ public AxPolicyModel(final AxArtifactKey key) {
+ this(key,
+ new AxContextSchemas(new AxArtifactKey(key.getName() + SCHEMAS_TOKEN, key.getVersion())),
+ new AxKeyInformation(new AxArtifactKey(key.getName() + KEY_INFO_TOKEN, key.getVersion())),
+ new AxEvents(new AxArtifactKey(key.getName() + EVENTS_TOKEN, key.getVersion())),
+ new AxContextAlbums(new AxArtifactKey(key.getName() + ALBUMS_TOKEN, key.getVersion())),
+ new AxTasks(new AxArtifactKey(key.getName() + TASKS_TOKEN, key.getVersion())),
+ new AxPolicies(new AxArtifactKey(key.getName() + POLICIESS_TOKEN, key.getVersion())));
+ }
+
+ /**
+ * This Constructor creates a policy model with all of its fields specified.
+ *
+ * @param key the key of the policy model
+ * @param schemas the context schema container for the policy model
+ * @param keyInformation the key information container for the policy model
+ * @param events the event container for the policy model
+ * @param albums the context album container for the policy model
+ * @param tasks the task container for the policy model
+ * @param policies the policy container for the policy model
+ */
+ public AxPolicyModel(final AxArtifactKey key, final AxContextSchemas schemas, final AxKeyInformation keyInformation,
+ final AxEvents events, final AxContextAlbums albums, final AxTasks tasks, final AxPolicies policies) {
+ super(key, keyInformation);
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ Assertions.argumentNotNull(events, "events may not be null");
+ Assertions.argumentNotNull(albums, "albums may not be null");
+ Assertions.argumentNotNull(tasks, "tasks may not be null");
+ Assertions.argumentNotNull(policies, "policies may not be null");
+
+ this.schemas = schemas;
+ this.events = events;
+ this.albums = albums;
+ this.tasks = tasks;
+ this.policies = policies;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void register() {
+ super.register();
+ ModelService.registerModel(AxContextSchemas.class, getSchemas());
+ ModelService.registerModel(AxEvents.class, getEvents());
+ ModelService.registerModel(AxContextAlbums.class, getAlbums());
+ ModelService.registerModel(AxTasks.class, getTasks());
+ ModelService.registerModel(AxPolicies.class, getPolicies());
+ ModelService.registerModel(AxPolicyModel.class, this);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = super.getKeys();
+
+ keyList.addAll(schemas.getKeys());
+ keyList.addAll(events.getKeys());
+ keyList.addAll(albums.getKeys());
+ keyList.addAll(tasks.getKeys());
+ keyList.addAll(policies.getKeys());
+
+ return keyList;
+ }
+
+ /**
+ * Gets a context model from the policy model.
+ *
+ * @return the context model
+ */
+ public AxContextModel getContextModel() {
+ return new AxContextModel(new AxArtifactKey(albums.getKey().getName() + "_Model", albums.getKey().getVersion()),
+ getSchemas(), getAlbums(), getKeyInformation());
+ }
+
+ /**
+ * Gets the policy container from the policy model.
+ *
+ * @return the policy container with all the policies in the model
+ */
+ public AxPolicies getPolicies() {
+ return policies;
+ }
+
+ /**
+ * Sets the policy container for the policy model.
+ *
+ * @param policies the policy container with all the policies in the model
+ */
+ public void setPolicies(final AxPolicies policies) {
+ Assertions.argumentNotNull(policies, "policies may not be null");
+ this.policies = policies;
+ }
+
+ /**
+ * Gets the task container from the policy model.
+ *
+ * @return the task container with all the tasks in the model
+ */
+ public AxTasks getTasks() {
+ return tasks;
+ }
+
+ /**
+ * Sets the task container from the policy model.
+ *
+ * @param tasks the task container with all the tasks in the model
+ */
+ public void setTasks(final AxTasks tasks) {
+ Assertions.argumentNotNull(tasks, "tasks may not be null");
+ this.tasks = tasks;
+ }
+
+ /**
+ * Gets the event container from the policy model.
+ *
+ * @return the event container with all the events in the model
+ */
+ public AxEvents getEvents() {
+ return events;
+ }
+
+ /**
+ * Sets the event container from the policy model.
+ *
+ * @param events the event container with all the events in the model
+ */
+ public void setEvents(final AxEvents events) {
+ Assertions.argumentNotNull(events, "events may not be null");
+ this.events = events;
+ }
+
+ /**
+ * Gets the context album container from the policy model.
+ *
+ * @return the context album container with all the context albums in the model
+ */
+ public AxContextAlbums getAlbums() {
+ return albums;
+ }
+
+ /**
+ * Sets the context album container from the policy model.
+ *
+ * @param albums the context album container with all the context albums in the model
+ */
+ public void setAlbums(final AxContextAlbums albums) {
+ Assertions.argumentNotNull(albums, "albums may not be null");
+ this.albums = albums;
+ }
+
+ /**
+ * Gets the context schema container from the policy model.
+ *
+ * @return the context schema container with all the context schemas in the model
+ */
+ public AxContextSchemas getSchemas() {
+ return schemas;
+ }
+
+ /**
+ * Sets the context schema container from the policy model.
+ *
+ * @param schemas the context schema container with all the context schemas in the model
+ */
+ public void setSchemas(final AxContextSchemas schemas) {
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ this.schemas = schemas;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ result = super.validate(result);
+ result = schemas.validate(result);
+ result = events.validate(result);
+ result = albums.validate(result);
+ result = tasks.validate(result);
+ result = policies.validate(result);
+
+ validateEventKeys(result);
+ validateContextAlbumKeys(result);
+ validateAllTaskKeys(result);
+ validatePolicyKeys(result);
+
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in events exist.
+ *
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validateEventKeys(final AxValidationResult result) {
+ for (final AxEvent event : events.getAll(null)) {
+ for (final AxField field : event.getFields()) {
+ if (getSchemas().get(field.getSchema()) == null) {
+ result.addValidationMessage(
+ new AxValidationMessage(event.getKey(), this.getClass(), ValidationResult.INVALID,
+ "event field data type " + field.getSchema().getId() + DOES_NOT_EXIST));
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in concept maps exist.
+ *
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validateContextAlbumKeys(final AxValidationResult result) {
+ for (final AxContextAlbum contextAlbum : albums.getAll(null)) {
+ if (getSchemas().get(contextAlbum.getItemSchema()) == null) {
+ result.addValidationMessage(
+ new AxValidationMessage(contextAlbum.getKey(), this.getClass(), ValidationResult.INVALID,
+ "context album schema " + contextAlbum.getItemSchema().getId() + DOES_NOT_EXIST));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in tasks exist.
+ *
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validateAllTaskKeys(AxValidationResult result) {
+ for (final AxTask task : tasks.getAll(null)) {
+ validateTaskKeys(task, result);
+ }
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in tasks exist.
+ *
+ * @param task The task to validate the keys of
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validateTaskKeys(final AxTask task, AxValidationResult result) {
+ for (final AxArtifactKey contextAlbumKey : task.getContextAlbumReferences()) {
+ if (albums.get(contextAlbumKey) == null) {
+ result.addValidationMessage(new AxValidationMessage(task.getKey(), this.getClass(),
+ ValidationResult.INVALID, "task context album " + contextAlbumKey.getId() + DOES_NOT_EXIST));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in policies exist.
+ *
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validatePolicyKeys(final AxValidationResult result) {
+ for (final AxPolicy policy : policies.getAll(null)) {
+ for (final AxState state : policy.getStateMap().values()) {
+ validateStateReferences(state, result);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate that the references used on a state are valid.
+ *
+ * @param state The state to check
+ * @param result the validation result to append to
+ */
+ private void validateStateReferences(AxState state, AxValidationResult result) {
+ for (final AxArtifactKey contextAlbumKey : state.getContextAlbumReferences()) {
+ if (albums.get(contextAlbumKey) == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state context album " + contextAlbumKey.getId() + DOES_NOT_EXIST));
+ }
+ }
+
+ final AxEvent triggerEvent = events.getEventMap().get(state.getTrigger());
+ if (triggerEvent == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state trigger event " + state.getTrigger().getId() + DOES_NOT_EXIST));
+ }
+
+ final AxTask defaultTask = tasks.getTaskMap().get(state.getDefaultTask());
+ if (defaultTask == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state default task " + state.getDefaultTask().getId() + DOES_NOT_EXIST));
+ }
+
+ for (final AxStateOutput stateOutput : state.getStateOutputs().values()) {
+ if (events.getEventMap().get(stateOutput.getOutgoingEvent()) == null) {
+ result.addValidationMessage(new AxValidationMessage(stateOutput.getKey(), this.getClass(),
+ ValidationResult.INVALID, "output event " + stateOutput.getOutgoingEvent().getId()
+ + " for state output " + stateOutput.getId() + DOES_NOT_EXIST));
+ }
+ }
+
+ validateEventTaskFieldCompatibilityOnState(state, result);
+ }
+
+ /**
+ * Validate that the fields on tasks and events that trigger them and are output by them are
+ * compatible for all tasks used on a state.
+ *
+ * @param state The state to check
+ * @param result the validation result to append to
+ */
+ private void validateEventTaskFieldCompatibilityOnState(AxState state, AxValidationResult result) {
+ // Check task output fields and event fields are compatible for tasks that directly
+ // reference state outputs
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskRefEntry : state.getTaskReferences().entrySet()) {
+ if (!taskRefEntry.getValue().getStateTaskOutputType().equals(AxStateTaskOutputType.DIRECT)) {
+ continue;
+ }
+
+ final AxTask usedTask = tasks.getTaskMap().get(taskRefEntry.getKey());
+ if (usedTask == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state task " + taskRefEntry.getKey().getId() + DOES_NOT_EXIST));
+ } else {
+ AxStateOutput stateOutput =
+ state.getStateOutputs().get(taskRefEntry.getValue().getOutput().getKey().getLocalName());
+ validateEventTaskFieldCompatibilityOnStateOutput(state, usedTask, stateOutput, result);
+ }
+ }
+ }
+
+ /**
+ * Validate that the fields on a task of a state output and the events that trigger it are
+ * compatible.
+ *
+ * @param state The state to check
+ * @param task The task to check
+ * @param stateOutput The state output to check
+ * @param result the validation result to append to
+ */
+ private void validateEventTaskFieldCompatibilityOnStateOutput(final AxState state, final AxTask task,
+ final AxStateOutput stateOutput, AxValidationResult result) {
+ if (stateOutput == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state output on task reference for task " + task.getId() + " is null"));
+
+ } else {
+ final AxEvent usedEvent = events.getEventMap().get(stateOutput.getOutgoingEvent());
+ if (usedEvent == null) {
+ result.addValidationMessage(new AxValidationMessage(stateOutput.getKey(), this.getClass(),
+ ValidationResult.INVALID, "output event " + stateOutput.getOutgoingEvent().getId()
+ + " for state output " + stateOutput.getId() + DOES_NOT_EXIST));
+ }
+ }
+ }
+
+ /**
+ * When a model is deserialized, if the albums field was missing a blank
+ * with a null key was added. This method is called by JAXB after deserializing and is
+ * used to insert an appropriate key
+ */
+ @Override
+ public void buildReferences() {
+ getSchemas().buildReferences();
+ getEvents().buildReferences();
+ getAlbums().buildReferences();
+ getTasks().buildReferences();
+ getPolicies().buildReferences();
+ getKeyInformation().buildReferences();
+
+ AxArtifactKey nullAlbumskey = new AxArtifactKey(AxKey.NULL_KEY_NAME + ALBUMS_TOKEN, AxKey.NULL_KEY_VERSION);
+
+ if (AxArtifactKey.getNullKey().equals(getAlbums().getKey())
+ || nullAlbumskey.equals(getAlbums().getKey())) {
+ getAlbums().setKey(new AxArtifactKey(getKey().getName() + ALBUMS_TOKEN, getKey().getVersion()));
+ getKeyInformation().generateKeyInfo(getAlbums());
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ super.clean();
+ policies.clean();
+ tasks.clean();
+ events.clean();
+ albums.clean();
+ schemas.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append(super.toString());
+ builder.append(",policies=");
+ builder.append(policies);
+ builder.append(",tasks=");
+ builder.append(tasks);
+ builder.append(",events=");
+ builder.append(events);
+ builder.append(",albums=");
+ builder.append(albums);
+ builder.append(",schemas=");
+ builder.append(schemas);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxPolicyModel.class);
+
+ final AxPolicyModel copy = ((AxPolicyModel) copyObject);
+ super.copyTo(targetObject);
+ copy.setPolicies(new AxPolicies(policies));
+ copy.setTasks(new AxTasks(tasks));
+ copy.setEvents(new AxEvents(events));
+ copy.setAlbums(new AxContextAlbums(albums));
+ copy.setSchemas(new AxContextSchemas(schemas));
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + super.hashCode();
+ result = prime * result + policies.hashCode();
+ result = prime * result + tasks.hashCode();
+ result = prime * result + events.hashCode();
+ result = prime * result + albums.hashCode();
+ result = prime * result + schemas.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ throw new IllegalArgumentException("comparison object may not be null");
+ }
+
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxPolicyModel other = (AxPolicyModel) obj;
+ if (!super.equals(other)) {
+ return false;
+ }
+ if (!policies.equals(other.policies)) {
+ return false;
+ }
+ if (!tasks.equals(other.tasks)) {
+ return false;
+ }
+ if (!events.equals(other.events)) {
+ return false;
+ }
+ if (!albums.equals(other.albums)) {
+ return false;
+ }
+ return schemas.equals(other.schemas);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxPolicyModel other = (AxPolicyModel) otherObj;
+ if (!super.equals(other)) {
+ return super.compareTo(other);
+ }
+ if (!policies.equals(other.policies)) {
+ return policies.compareTo(other.policies);
+ }
+ if (!tasks.equals(other.tasks)) {
+ return tasks.compareTo(other.tasks);
+ }
+ if (!events.equals(other.events)) {
+ return events.compareTo(other.events);
+ }
+ if (!albums.equals(other.albums)) {
+ return albums.compareTo(other.albums);
+ }
+ return schemas.compareTo(other.schemas);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java
new file mode 100644
index 000000000..ae8efbff4
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java
@@ -0,0 +1,870 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import com.google.gson.annotations.SerializedName;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class holds the definition of a single state in a policy. A state is a single stage in a policy. A state has a
+ * single input event, its trigger. A state can output many events, but can only output one event on a single execution.
+ * After it executes, a state can pass control to another state or can simply emit its event to an external system. In
+ * the case where a state passes control to another state, the output event of the state becomes the input event of the
+ * next state. The outputs of a state {@link AxStateOutput} are held as a map in the state. Each state output contains
+ * the outgoing event of the state and optionally the next state to pass control to.
+ *
+ * <p>A state uses tasks {@link AxTask} to execute its logic. A state holds its tasks in a map and must have at least
+ * one task. A state uses Task Selection Logic {@link AxTaskSelectionLogic} to select which task should be executed in a
+ * given execution cycle. Optional Task Selection Logic can use fields on the incoming event and information from the
+ * context albums available on the state to decide what task to execute in a given context. The default task of a state
+ * is the task that is executed when task Selection Logic is not specified. In cases where only a single task is
+ * specified on a state, the default task must be that task and the state always executes that task.
+ *
+ * <p>What happens when a state completes its execution cycle depends on the task that is selected for execution by the
+ * state. Therefore, the action to be performed a state on execution of each task must be defined in the state as a
+ * {@link AxStateTaskReference} instance for each task defined in the state. The {@link AxStateTaskReference} instance
+ * defines the action to be performed as either a {@link AxStateTaskOutputType} of {@link AxStateTaskOutputType#DIRECT}
+ * or {@link AxStateTaskOutputType#LOGIC} and contains an {@link AxReferenceKey} reference to the instance that will
+ * complete the state output.
+ *
+ * <p>In the case of direct output, the {@link AxReferenceKey} reference in the {@link AxStateTaskReference} instance is
+ * a reference to an {@link AxStateOutput} instance. The state output defines the event to be emitted by the state and
+ * the next state to pass control to if any. All fields of the executed task are marshaled onto the outgoing event
+ * automatically by Apex.
+ *
+ * <p>In the case of logic output, the {@link AxReferenceKey} reference in the {@link AxStateTaskReference} instance is
+ * a reference to State Finalizer Logic in an {@link AxStateFinalizerLogic} instance, which selects the
+ * {@link AxStateOutput} that the state will use. The state finalizer logic uses fields emitted by the executed task and
+ * information from the context albums available on the state to decide what {@link AxStateOutput} to select in a given
+ * context. The state output defines the event to be emitted by the state and the next state to pass control to if any.
+ * The State Finalizer Logic instances for the state are held in a map in the state. State Finalizer Logic must marshal
+ * the fields of the output event in whatever manner it wishes; Apex does not automatically transfer the output fields
+ * from the task directly to the output event.
+ *
+ * <p>The Task Selection Logic instance or State Finalizer Logic instances in a state may use information in context
+ * albums to arrive at their task or state output selections. The context albums that the state uses and that should be
+ * made available to the state by Apex policy distribution are held as a set of references to context albums in the
+ * state.
+ *
+ * <p>During validation of a state, the validation checks listed below are executed: <ol> <li>The policy key must not be
+ * a null key and must be valid, see validation in {@link AxReferenceKey} <li>The trigger event key must not be a null
+ * key and must be valid, see validation in {@link AxArtifactKey} <li>At least one state output must be defined <li>Each
+ * state output in a state must have that state as its parent <li>Each state output must be valid, see validation in
+ * {@link AxStateOutput} <li>The next state defined in a state output must be unique in a state <li>The default task key
+ * must not be a null key and must be valid, see validation in {@link AxArtifactKey} <li>The default task must appear in
+ * the task map of the state <li>At least one task must be defined on the state <li>Each task key on the task map for
+ * the state must not be a null key and must be valid, see validation in {@link AxArtifactKey} <li>All state task
+ * references for each task in the state must exist and must be valid, see validation in {@link AxStateTaskReference}
+ * <li>Each state task reference in a state must have that state as its parent <li>For direct state outputs from tasks,
+ * the state output must be defined on the state <li>For logic state outputs from tasks, the State Finalizer Logic must
+ * be defined on the state <li>An observation is issued for each state output defined on the state that is not used as a
+ * direct output on a task <li>An observation is issued for each state finalizer logic instance defined on the state
+ * that is not used as an output on a task <li>Each context album key on the context album set for the state must not be
+ * a null key and must be valid, see validation in {@link AxArtifactKey} <li>Task Selection logic in a state must have
+ * that state as its parent <li>Task Selection logic in a state must be valid, see validation in
+ * {@link AxTaskSelectionLogic} <li>Each State Finalizer logic instance in a state must have that state as its parent
+ * <li>Each State Finalizer logic instance in a state must be valid, see validation in {@link AxStateFinalizerLogic}
+ * </ol>
+ */
+public class AxState extends AxConcept {
+ private static final String DOES_NOT_EQUAL_STATE_KEY = " does not equal state key";
+
+ private static final long serialVersionUID = 8041771382337655535L;
+
+
+
+ @SerializedName("stateKey")
+ private AxReferenceKey key;
+
+ private AxArtifactKey trigger;
+ private Map<String, AxStateOutput> stateOutputs;
+
+ @SerializedName("contextAlbumReference")
+ private Set<AxArtifactKey> contextAlbumReferenceSet;
+
+ private AxTaskSelectionLogic taskSelectionLogic;
+ private Map<String, AxStateFinalizerLogic> stateFinalizerLogicMap;
+ private AxArtifactKey defaultTask;
+
+ @SerializedName("taskReferences")
+ private Map<AxArtifactKey, AxStateTaskReference> taskReferenceMap;
+
+ /**
+ * The Default Constructor creates a state with a null reference key and with default values for all other fields.
+ */
+ public AxState() {
+ this(new AxReferenceKey());
+ contextAlbumReferenceSet = new TreeSet<>();
+ taskReferenceMap = new TreeMap<>();
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxState(final AxState copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a state with the given reference key and with default values for all other fields.
+ *
+ * @param key the reference key of the state
+ */
+ public AxState(final AxReferenceKey key) {
+ // @formatter:off
+ this(new AxStateParamsBuilder()
+ .key(key) // Key
+ .trigger(AxArtifactKey.getNullKey()) // Trigger Reference
+ .stateOutputs(new TreeMap<>()) // State Outputs
+ .contextAlbumReferenceSet(new TreeSet<>()) // Context Album Refs
+ .taskSelectionLogic(new AxTaskSelectionLogic()) // Task Selection Logic
+ .stateFinalizerLogicMap(new TreeMap<>()) // State Finalizer Logics
+ .defaultTask(AxArtifactKey.getNullKey()) // Default Task
+ .taskReferenceMap(new TreeMap<>()) // Task References
+ );
+ // @formatter:on
+ }
+
+ /**
+ * This Constructor creates a state with all its fields defined.
+ *
+ * @param axStateParams parameters for state creation
+ */
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ public AxState(AxStateParamsBuilder axStateParams) {
+ super();
+ Assertions.argumentNotNull(axStateParams.getKey(), "key may not be null");
+ Assertions.argumentNotNull(axStateParams.getTrigger(), "trigger may not be null");
+ Assertions.argumentNotNull(axStateParams.getStateOutputs(), "stateOutputs may not be null");
+ Assertions.argumentNotNull(axStateParams.getContextAlbumReferenceSet(),
+ "contextAlbumReferenceSet may not be null");
+ Assertions.argumentNotNull(axStateParams.getTaskSelectionLogic(), "taskSelectionLogic may not be null");
+ Assertions.argumentNotNull(axStateParams.getStateFinalizerLogicMap(), "stateFinalizerLogicMap may not be null");
+ Assertions.argumentNotNull(axStateParams.getDefaultTask(), "defaultTask may not be null");
+ Assertions.argumentNotNull(axStateParams.getTaskReferenceMap(), "taskReferenceMap may not be null");
+
+ this.key = axStateParams.getKey();
+ this.trigger = axStateParams.getTrigger();
+ this.stateOutputs = axStateParams.getStateOutputs();
+ this.contextAlbumReferenceSet = axStateParams.getContextAlbumReferenceSet();
+ this.taskSelectionLogic = axStateParams.getTaskSelectionLogic();
+ this.stateFinalizerLogicMap = axStateParams.getStateFinalizerLogicMap();
+ this.defaultTask = axStateParams.getDefaultTask();
+ this.taskReferenceMap = axStateParams.getTaskReferenceMap();
+ }
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * When a state is deserialized from disk or from the database, the parent of contained objects is not defined. This
+ * method is called by JAXB after deserialized and is used to set the parent keys of all
+ * {@link AxTaskSelectionLogic}, {@link AxStateOutput}, and {@link AxStateFinalizerLogic} instance in the state.
+ */
+ @Override
+ public void buildReferences() {
+ if (!taskSelectionLogic.getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ taskSelectionLogic.getKey().setParentReferenceKey(key);
+ }
+
+ stateOutputs.values().stream().forEach(output -> output.getKey().setParentReferenceKey(key));
+ stateFinalizerLogicMap.values().stream().forEach(output -> output.getKey().setParentReferenceKey(key));
+ taskReferenceMap.values().stream().forEach(output -> output.getKey().setParentReferenceKey(key));
+ }
+
+ /**
+ * Gets the names of all the states that this state may pass control to.
+ *
+ * @return the list of possible states that may receive control when this state completes execution
+ */
+ public Set<String> getNextStateSet() {
+ final Set<String> nextStateSet = new TreeSet<>();
+
+ for (final AxStateOutput stateOutput : stateOutputs.values()) {
+ nextStateSet.add(stateOutput.getNextState().getLocalName());
+ }
+ return nextStateSet;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.add(new AxKeyUse(trigger.getKey()));
+ for (final AxStateOutput stateOutput : stateOutputs.values()) {
+ keyList.addAll(stateOutput.getKeys());
+ }
+ for (final AxArtifactKey contextAlbumReferenceKey : contextAlbumReferenceSet) {
+ keyList.add(new AxKeyUse(contextAlbumReferenceKey));
+ }
+ if (!taskSelectionLogic.getKey().equals(AxReferenceKey.getNullKey())) {
+ keyList.addAll(taskSelectionLogic.getKeys());
+ }
+ for (final Entry<String, AxStateFinalizerLogic> stateFinalizerLogicEntry : stateFinalizerLogicMap.entrySet()) {
+ keyList.addAll(stateFinalizerLogicEntry.getValue().getKeys());
+ }
+ keyList.add(new AxKeyUse(defaultTask.getKey()));
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskReferenceEntry : taskReferenceMap.entrySet()) {
+ keyList.add(new AxKeyUse(taskReferenceEntry.getKey()));
+
+ // A state output is allowed to be used more than once but we only return one usage as a
+ // key
+ for (AxKey referencedKey : taskReferenceEntry.getValue().getKeys()) {
+ if (keyList.contains(referencedKey)) {
+ keyList.add(referencedKey);
+ }
+ }
+ }
+ return keyList;
+ }
+
+ /**
+ * Sets the reference key of the state.
+ *
+ * @param key the state reference key
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the event that triggers the state.
+ *
+ * @return the event that triggers the state
+ */
+ public AxArtifactKey getTrigger() {
+ return trigger;
+ }
+
+ /**
+ * Sets the event that triggers the state.
+ *
+ * @param trigger the event that triggers the state
+ */
+ public void setTrigger(final AxArtifactKey trigger) {
+ Assertions.argumentNotNull(trigger, "trigger may not be null");
+ this.trigger = trigger;
+ }
+
+ /**
+ * Gets the possible state outputs for the state.
+ *
+ * @return the the possible state outputs for the state
+ */
+ public Map<String, AxStateOutput> getStateOutputs() {
+ return stateOutputs;
+ }
+
+ /**
+ * Sets the the possible state outputs for the state.
+ *
+ * @param stateOutputs the the possible state outputs for the state
+ */
+ public void setStateOutputs(final Map<String, AxStateOutput> stateOutputs) {
+ Assertions.argumentNotNull(stateOutputs, "stateOutputs may not be null");
+ this.stateOutputs = stateOutputs;
+ }
+
+ /**
+ * Gets the context album reference set defines the context that may be used by Task Selection Logic and State
+ * Finalizer Logic in the state.
+ *
+ * @return the context album reference set defines the context that may be used by Task Selection Logic and State
+ * Finalizer Logic in the state
+ */
+ public Set<AxArtifactKey> getContextAlbumReferences() {
+ return contextAlbumReferenceSet;
+ }
+
+ /**
+ * Sets the context album reference set defines the context that may be used by Task Selection Logic and State
+ * Finalizer Logic in the state.
+ *
+ * @param contextAlbumReferences the context album reference set defines the context that may be used by Task
+ * Selection Logic and State Finalizer Logic in the state
+ */
+ public void setContextAlbumReferences(final Set<AxArtifactKey> contextAlbumReferences) {
+ Assertions.argumentNotNull(contextAlbumReferences, "contextAlbumReferenceSet may not be null");
+ this.contextAlbumReferenceSet = contextAlbumReferences;
+ }
+
+ /**
+ * Gets the task selection logic that selects the task a state executes in an execution cycle.
+ *
+ * @return the task selection logic that selects the task a state executes in an execution cycle
+ */
+ public AxTaskSelectionLogic getTaskSelectionLogic() {
+ return taskSelectionLogic;
+ }
+
+ /**
+ * Sets the task selection logic that selects the task a state executes in an execution cycle.
+ *
+ * @param taskSelectionLogic the task selection logic that selects the task a state executes in an execution cycle
+ */
+ public void setTaskSelectionLogic(final AxTaskSelectionLogic taskSelectionLogic) {
+ Assertions.argumentNotNull(taskSelectionLogic, "taskSelectionLogic may not be null");
+ this.taskSelectionLogic = taskSelectionLogic;
+ }
+
+ /**
+ * Check if task selection logic has been specified the state.
+ *
+ * @return true, if task selection logic has been specified
+ */
+ public boolean checkSetTaskSelectionLogic() {
+ return !taskSelectionLogic.getKey().equals(AxReferenceKey.getNullKey());
+ }
+
+ /**
+ * Gets the state finalizer logic instances that selects the state output to use after a task executes in a state
+ * execution cycle.
+ *
+ * @return the state finalizer logic instances that selects the state output to use after a task executes in a state
+ * execution cycle
+ */
+ public Map<String, AxStateFinalizerLogic> getStateFinalizerLogicMap() {
+ return stateFinalizerLogicMap;
+ }
+
+ /**
+ * Sets the state finalizer logic instances that selects the state output to use after a task executes in a state
+ * execution cycle.
+ *
+ * @param stateFinalizerLogicMap the state finalizer logic instances that selects the state output to use after a
+ * task executes in a state execution cycle
+ */
+ public void setStateFinalizerLogicMap(final Map<String, AxStateFinalizerLogic> stateFinalizerLogicMap) {
+ Assertions.argumentNotNull(stateFinalizerLogicMap, "stateFinalizerLogic may not be null");
+ this.stateFinalizerLogicMap = stateFinalizerLogicMap;
+ }
+
+ /**
+ * Gets the default task that will execute in a state if Task Selection Logic is not specified.
+ *
+ * @return the default task that will execute in a state if Task Selection Logic is not specified
+ */
+ public AxArtifactKey getDefaultTask() {
+ return defaultTask;
+ }
+
+ /**
+ * Sets the default task that will execute in a state if Task Selection Logic is not specified.
+ *
+ * @param defaultTask the default task that will execute in a state if Task Selection Logic is not specified
+ */
+ public void setDefaultTask(final AxArtifactKey defaultTask) {
+ Assertions.argumentNotNull(defaultTask, "defaultTask may not be null");
+ this.defaultTask = defaultTask;
+ }
+
+ /**
+ * Gets the task reference map that defines the tasks for the state and how the task outputs are handled.
+ *
+ * @return the task reference map that defines the tasks for the state and how the task outputs are handled
+ */
+ public Map<AxArtifactKey, AxStateTaskReference> getTaskReferences() {
+ return taskReferenceMap;
+ }
+
+ /**
+ * Sets the task reference map that defines the tasks for the state and how the task outputs are handled.
+ *
+ * @param taskReferences the task reference map that defines the tasks for the state and how the task outputs are
+ * handled
+ */
+ public void setTaskReferences(final Map<AxArtifactKey, AxStateTaskReference> taskReferences) {
+ Assertions.argumentNotNull(taskReferences, "taskReferenceMap may not be null");
+ this.taskReferenceMap = taskReferences;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (trigger.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "trigger is a null key: " + trigger));
+ }
+ result = trigger.validate(result);
+
+ if (stateOutputs.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateOutputs may not be empty"));
+ } else {
+ validateStateOutputs(result);
+ }
+
+ validateContextAlbumReferences(result);
+ result = validateTaskSelectionLogic(result);
+ validateStateFinalizerLogics(result);
+
+ if (defaultTask.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "default task has a null key: " + defaultTask));
+ }
+ result = defaultTask.validate(result);
+
+ if (taskReferenceMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "taskReferenceMap may not be empty"));
+ } else {
+ validateStateTaskReferences(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate the state outputs of the state.
+ *
+ * @param result the validation result to append to
+ */
+ private void validateStateOutputs(AxValidationResult result) {
+ final Set<String> nextStateNameSet = new TreeSet<>();
+ for (final Entry<String, AxStateOutput> stateOutputEntry : stateOutputs.entrySet()) {
+ if (stateOutputEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null state output value found on state output " + stateOutputEntry.getKey()));
+ } else {
+ if (!stateOutputEntry.getValue().getKey().getParentReferenceKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent key on state output " + stateOutputEntry.getKey()
+ + DOES_NOT_EQUAL_STATE_KEY));
+ }
+
+ if (stateOutputEntry.getValue().getNextState().getLocalName().equals(key.getLocalName())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "state output next state "
+ + stateOutputEntry.getValue().getNextState().getLocalName()
+ + " may not be this state"));
+
+ }
+
+ if (nextStateNameSet.contains(stateOutputEntry.getValue().getNextState().getLocalName())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "duplicate state output next state name "
+ + stateOutputEntry.getValue().getNextState().getLocalName()
+ + " found"));
+ } else {
+ nextStateNameSet.add(stateOutputEntry.getValue().getNextState().getLocalName());
+ }
+ result = stateOutputEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ /**
+ * Validate the context album references of the state.
+ *
+ * @param result the validation result to append to
+ */
+ private void validateContextAlbumReferences(AxValidationResult result) {
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ if (contextAlbumReference.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on context album reference entry " + contextAlbumReference.getKey()
+ + " may not be the null key"));
+ }
+
+ result = contextAlbumReference.validate(result);
+ }
+ }
+
+ /**
+ * Validate the task selection logic of the state.
+ *
+ * @param result the validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateTaskSelectionLogic(AxValidationResult result) {
+ if (!taskSelectionLogic.getKey().equals(AxReferenceKey.getNullKey())) {
+ if (!taskSelectionLogic.getKey().getParentReferenceKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "taskSelectionLogic key " + taskSelectionLogic.getKey().getId()
+ + DOES_NOT_EQUAL_STATE_KEY));
+ }
+ result = taskSelectionLogic.validate(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate all the state finalizer logic of the state.
+ *
+ * @param result the validation result to append to
+ */
+ private void validateStateFinalizerLogics(AxValidationResult result) {
+ for (final Entry<String, AxStateFinalizerLogic> stateFinalizerLogicEntry : stateFinalizerLogicMap.entrySet()) {
+ if (stateFinalizerLogicEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null state finalizer logic value found on state finalizer entry "
+ + stateFinalizerLogicEntry.getKey()));
+ } else {
+ if (!stateFinalizerLogicEntry.getValue().getKey().getParentReferenceKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateFinalizerLogic parent key "
+ + stateFinalizerLogicEntry.getValue().getKey().getId()
+ + DOES_NOT_EQUAL_STATE_KEY));
+ }
+
+ result = stateFinalizerLogicEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ /**
+ * Validate the tasks used the state.
+ *
+ * @param result the validation result to append to
+ */
+ private void validateStateTaskReferences(AxValidationResult result) {
+ final Set<String> usedStateOutputNameSet = new TreeSet<>();
+ final Set<String> usedStateFinalizerLogicNameSet = new TreeSet<>();
+
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskRefEntry : taskReferenceMap.entrySet()) {
+ if (taskRefEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "task has a null key: " + taskRefEntry.getKey()));
+ }
+ result = taskRefEntry.getKey().validate(result);
+
+ if (taskRefEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null task reference value found on task reference " + taskRefEntry.getKey()));
+ } else {
+ result = validateStateTaskReference(taskRefEntry.getKey(), taskRefEntry.getValue(),
+ usedStateOutputNameSet, usedStateFinalizerLogicNameSet, result);
+ }
+ }
+
+ final Set<String> unUsedStateOutputNameSet = new TreeSet<>(stateOutputs.keySet());
+ unUsedStateOutputNameSet.removeAll(usedStateOutputNameSet);
+ for (final String unUsedStateOutputName : unUsedStateOutputNameSet) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "state output " + unUsedStateOutputName + " is not used directly by any task"));
+ }
+
+ final Set<String> usnUedStateFinalizerLogicNameSet = new TreeSet<>(stateFinalizerLogicMap.keySet());
+ usnUedStateFinalizerLogicNameSet.removeAll(usedStateFinalizerLogicNameSet);
+ for (final String unusedStateFinalizerLogicName : usnUedStateFinalizerLogicNameSet) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "state finalizer logic " + unusedStateFinalizerLogicName + " is not used by any task"));
+ }
+
+ if (!taskReferenceMap.containsKey(defaultTask)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "defaultTask " + defaultTask + " not found in taskReferenceMap"));
+ }
+ }
+
+ /**
+ * Validate the references of a task used in a state.
+ *
+ * @param taskKey The key of the task
+ * @param taskReference the task reference of the task
+ * @param stateOutputNameSet State outputs that have been used so far, will be appended for this task reference
+ * @param stateFinalizerLogicNameSet State finalizers that have been used so far, may be appended if this task
+ * reference uses a finalzier
+ * @param result the validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateStateTaskReference(final AxArtifactKey taskKey,
+ final AxStateTaskReference taskReference, Set<String> stateOutputNameSet,
+ Set<String> stateFinalizerLogicNameSet, AxValidationResult result) {
+ if (!taskReference.getKey().getParentReferenceKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateTaskReference parent key " + taskReference.getKey().getId()
+ + DOES_NOT_EQUAL_STATE_KEY));
+ }
+
+ if (taskReference.getStateTaskOutputType().equals(AxStateTaskOutputType.DIRECT)) {
+ if (stateOutputs.containsKey(taskReference.getOutput().getLocalName())) {
+ stateOutputNameSet.add(taskReference.getOutput().getLocalName());
+ } else {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "state output for task " + taskKey + " not found in stateOutputs"));
+ }
+ } else if (taskReference.getStateTaskOutputType().equals(AxStateTaskOutputType.LOGIC)) {
+ if (stateFinalizerLogicMap.containsKey(taskReference.getOutput().getLocalName())) {
+ stateFinalizerLogicNameSet.add(taskReference.getOutput().getLocalName());
+ } else {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "state finalizer logic for task " + taskKey + " not found in stateFinalizerLogicMap"));
+ }
+ } else {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateTaskReference task output type " + taskReference.getStateTaskOutputType()
+ + " is invalid"));
+ }
+
+ return taskReference.validate(result);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ trigger.clean();
+ for (final AxStateOutput stateOutput : stateOutputs.values()) {
+ stateOutput.clean();
+ }
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ contextAlbumReference.clean();
+ }
+ taskSelectionLogic.clean();
+ for (final AxStateFinalizerLogic stateFinalizerLogic : stateFinalizerLogicMap.values()) {
+ stateFinalizerLogic.clean();
+ }
+ defaultTask.clean();
+ for (final AxStateTaskReference taskReference : taskReferenceMap.values()) {
+ taskReference.clean();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("stateKey=");
+ builder.append(key);
+ builder.append(",trigger=");
+ builder.append(trigger);
+ builder.append(",stateOutputs=");
+ builder.append(stateOutputs);
+ builder.append(",contextAlbumReferenceSet=");
+ builder.append(contextAlbumReferenceSet);
+ builder.append(",taskSelectionLogic=");
+ builder.append(taskSelectionLogic);
+ builder.append(",stateFinalizerLogicSet=");
+ builder.append(stateFinalizerLogicMap);
+ builder.append(",defaultTask=");
+ builder.append(defaultTask);
+ builder.append(",taskReferenceMap=");
+ builder.append(taskReferenceMap);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxState.class);
+
+ final AxState copy = ((AxState) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setTrigger(new AxArtifactKey(trigger));
+
+ final Map<String, AxStateOutput> newStateOutputs = new TreeMap<>();
+ for (final Entry<String, AxStateOutput> stateOutputEntry : stateOutputs.entrySet()) {
+ newStateOutputs.put(stateOutputEntry.getKey(), new AxStateOutput(stateOutputEntry.getValue()));
+ }
+ copy.setStateOutputs(newStateOutputs);
+
+ final Set<AxArtifactKey> newContextUsage = new TreeSet<>();
+ for (final AxArtifactKey contextAlbumReferenceItem : contextAlbumReferenceSet) {
+ newContextUsage.add(new AxArtifactKey(contextAlbumReferenceItem));
+ }
+ copy.setContextAlbumReferences(newContextUsage);
+
+ copy.setTaskSelectionLogic(new AxTaskSelectionLogic(taskSelectionLogic));
+
+ final Map<String, AxStateFinalizerLogic> newStateFinalizerLogicMap = new TreeMap<>();
+ for (final Entry<String, AxStateFinalizerLogic> stateFinalizerLogicEntry : stateFinalizerLogicMap.entrySet()) {
+ newStateFinalizerLogicMap.put(stateFinalizerLogicEntry.getKey(),
+ new AxStateFinalizerLogic(stateFinalizerLogicEntry.getValue()));
+ }
+ copy.setStateFinalizerLogicMap(newStateFinalizerLogicMap);
+
+ copy.setDefaultTask(new AxArtifactKey(defaultTask));
+
+ final Map<AxArtifactKey, AxStateTaskReference> newTaskReferenceMap = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskReferenceEntry : taskReferenceMap.entrySet()) {
+ newTaskReferenceMap.put(new AxArtifactKey(taskReferenceEntry.getKey()),
+ new AxStateTaskReference(taskReferenceEntry.getValue()));
+ }
+ copy.setTaskReferences(newTaskReferenceMap);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + trigger.hashCode();
+ result = prime * result + stateOutputs.hashCode();
+ result = prime * result + contextAlbumReferenceSet.hashCode();
+ result = prime * result + taskSelectionLogic.hashCode();
+ result = prime * result + stateFinalizerLogicMap.hashCode();
+ result = prime * result + defaultTask.hashCode();
+ result = prime * result + taskReferenceMap.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxState other = (AxState) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!trigger.equals(other.trigger)) {
+ return false;
+ }
+ if (!stateOutputs.equals(other.stateOutputs)) {
+ return false;
+ }
+ if (!contextAlbumReferenceSet.equals(other.contextAlbumReferenceSet)) {
+ return false;
+ }
+ if (!taskSelectionLogic.equals(other.taskSelectionLogic)) {
+ return false;
+ }
+ if (!stateFinalizerLogicMap.equals(other.stateFinalizerLogicMap)) {
+ return false;
+ }
+ if (!defaultTask.equals(other.defaultTask)) {
+ return false;
+ }
+ return taskReferenceMap.equals(other.taskReferenceMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ return compareObjectFields((AxState) otherObj);
+ }
+
+ /**
+ * Compare the object fields on this state to another state.
+ *
+ * @param other the other state to compare with
+ * @return the result of the comparison
+ */
+ private int compareObjectFields(final AxState other) {
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!trigger.equals(other.trigger)) {
+ return trigger.compareTo(other.trigger);
+ }
+ if (!stateOutputs.equals(other.stateOutputs)) {
+ return stateOutputs.hashCode() - other.stateOutputs.hashCode();
+ }
+ if (!contextAlbumReferenceSet.equals(other.contextAlbumReferenceSet)) {
+ return (contextAlbumReferenceSet.hashCode() - other.contextAlbumReferenceSet.hashCode());
+ }
+ if (!taskSelectionLogic.equals(other.taskSelectionLogic)) {
+ return taskSelectionLogic.compareTo(other.taskSelectionLogic);
+ }
+ if (!stateFinalizerLogicMap.equals(other.stateFinalizerLogicMap)) {
+ return stateFinalizerLogicMap.hashCode() - other.stateFinalizerLogicMap.hashCode();
+ }
+ if (!defaultTask.equals(other.defaultTask)) {
+ return defaultTask.compareTo(other.defaultTask);
+ }
+ if (!taskReferenceMap.equals(other.taskReferenceMap)) {
+ return (taskReferenceMap.hashCode() - other.taskReferenceMap.hashCode());
+ }
+
+ return 0;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateFinalizerLogic.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateFinalizerLogic.java
new file mode 100644
index 000000000..31ffedea8
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateFinalizerLogic.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.policymodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+/**
+ * This class holds State Finalizer Logic for {@link AxState} states in Apex. It is a specialization
+ * of the {@link AxLogic} class, so that State Finalizer Logic in Apex states can be strongly typed.
+ *
+ * <p>State Finalizer Logic is used to select the output {@link AxStateOutput} that a state will use.
+ * The logic uses fields emitted by the executed {@link AxTask} task and information from the
+ * context albums available on a state to decide what state output {@link AxStateOutput} to select
+ * in a given context. State Finalizer Logic must marshal the output fields from the task onto the
+ * output event in whatever manner is appropriate for the domain being handled.
+ *
+ * <p>Validation uses standard Apex Logic validation, see validation in {@link AxLogic}.
+ */
+public class AxStateFinalizerLogic extends AxLogic {
+ private static final long serialVersionUID = 2090324845463750391L;
+
+ /**
+ * The Default Constructor creates a logic instance with a null key, undefined logic flavour and
+ * a null logic string.
+ */
+ public AxStateFinalizerLogic() {
+ super();
+ }
+
+ /**
+ * The Key Constructor creates a logic instance with the given reference key, undefined logic
+ * flavour and a null logic string.
+ *
+ * @param key the reference key of the logic
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey key) {
+ super(key, LOGIC_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name and all of its fields defined.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final String logic) {
+ super(parentKey, logicName, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and all of its fields
+ * defined.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey key, final String logicFlavour, final String logic) {
+ super(key, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance by cloning the fields from another logic instance
+ * into this logic instance.
+ *
+ * @param logic the logic instance to clone from
+ */
+ public AxStateFinalizerLogic(final AxLogic logic) {
+ super(new AxReferenceKey(logic.getKey()), logic.getLogicFlavour(), logic.getLogic());
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name, the given logic flavour, with the logic being provided by the
+ * given logic reader instance.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final AxLogicReader logicReader) {
+ super(new AxReferenceKey(parentKey, logicName), logicFlavour, logicReader);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and logic flavour, the
+ * logic is provided by the given logic reader instance.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey key, final String logicFlavour, final AxLogicReader logicReader) {
+ super(key, logicFlavour, logicReader);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java
new file mode 100644
index 000000000..7d4695290
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java
@@ -0,0 +1,291 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import com.google.gson.annotations.SerializedName;
+import java.util.List;
+import java.util.Set;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.Setter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class defines a single output that a state can have. A state can have many outputs with each
+ * output defined as an instance of this class. Each state output defines the output event that will
+ * be emitted when this output is selected and optionally the next state that is executed when this
+ * state output is selected. If no next state is defined (the next state is a null
+ * {@link AxReferenceKey} key), then this state output outputs its event to an external system and
+ * is an output state for the full policy.
+ *
+ * <p>During validation of a state output, the validation checks listed below are executed:
+ * <ol>
+ * <li>The state output key must not be a null key and must be valid, see validation in
+ * {@link AxReferenceKey}
+ * <li>The outgoing event key must not be a null key and must be valid, see validation in
+ * {@link AxArtifactKey}
+ * <li>The next state key must be valid, see validation in {@link AxReferenceKey}
+ * </ol>
+ */
+@Getter
+@Setter
+public class AxStateOutput extends AxConcept {
+ private static final long serialVersionUID = 8041771382337655535L;
+
+ @NonNull
+ private AxReferenceKey key;
+
+ @NonNull
+ private AxArtifactKey outgoingEvent;
+
+ @SerializedName("outgoingEventReference")
+ private Set<AxArtifactKey> outgoingEventSet;
+
+ @NonNull
+ private AxReferenceKey nextState;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a state output instance with a null reference key, outgoing
+ * event key and next state reference key.
+ */
+ public AxStateOutput() {
+ this(new AxReferenceKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxStateOutput(final AxStateOutput copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a state output instance with the given reference key, outgoing
+ * event key and next state reference key.
+ *
+ * @param key the reference key for the state output
+ */
+ public AxStateOutput(final AxReferenceKey key) {
+ this(key, // Key
+ AxArtifactKey.getNullKey(), // Outgoing Event
+ AxReferenceKey.getNullKey() // Next State
+ );
+ }
+
+ /**
+ * This Constructor creates a state output with a reference key composed of the given parent key
+ * and with a local name composed from the parent key local name concatenated with the next
+ * state's local name. The next state and outgoing event of the state output are set as
+ * specified.
+ *
+ * @param parentKey the parent key of the state output
+ * @param nextState the next state to which execution will pass on use of this state output
+ * @param outgoingEvent the outgoing event emitted on use of this state output
+ */
+ public AxStateOutput(final AxReferenceKey parentKey, final AxReferenceKey nextState,
+ final AxArtifactKey outgoingEvent) {
+ this(new AxReferenceKey(parentKey, parentKey.getLocalName() + '_' + nextState.getLocalName()), outgoingEvent,
+ nextState);
+ }
+
+ /**
+ * This Constructor creates a state output with the specified reference key. The next state and
+ * outgoing event of the state output are set as specified.
+ *
+ * @param key the key
+ * @param nextState the next state to which execution will pass on use of this state output
+ * @param outgoingEvent the outgoing event emitted on use of this state output
+ */
+ public AxStateOutput(final AxReferenceKey key, final AxArtifactKey outgoingEvent, final AxReferenceKey nextState) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(outgoingEvent, "outgoingEvent may not be null");
+ Assertions.argumentNotNull(nextState, "nextState may not be null");
+
+ this.key = key;
+ this.outgoingEvent = outgoingEvent;
+ this.nextState = nextState;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.add(new AxKeyUse(outgoingEvent));
+
+ if (!nextState.equals(AxReferenceKey.getNullKey())) {
+ keyList.add(new AxKeyUse(nextState));
+ }
+
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (outgoingEvent.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "outgoingEvent reference is a null key, an outgoing event must be specified"));
+ }
+ result = outgoingEvent.validate(result);
+
+ // Note: Null keys are allowed on nextState as there may not be a next state
+ result = nextState.validate(result);
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ outgoingEvent.clean();
+ nextState.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("stateKey=");
+ builder.append(key);
+ builder.append(",outgoingEvent=");
+ builder.append(outgoingEvent);
+ builder.append(",nextState=");
+ builder.append(nextState);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxStateOutput.class);
+
+ final AxStateOutput copy = ((AxStateOutput) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setOutgoingEvent(new AxArtifactKey(outgoingEvent));
+ copy.setNextState(nextState);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + outgoingEvent.hashCode();
+ result = prime * result + nextState.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxStateOutput other = (AxStateOutput) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!outgoingEvent.equals(other.outgoingEvent)) {
+ return false;
+ }
+ return nextState.equals(other.nextState);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxStateOutput other = (AxStateOutput) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!outgoingEvent.equals(other.outgoingEvent)) {
+ return outgoingEvent.compareTo(other.outgoingEvent);
+ }
+ return nextState.compareTo(other.nextState);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateParamsBuilder.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateParamsBuilder.java
new file mode 100644
index 000000000..6ef6e0b0a
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateParamsBuilder.java
@@ -0,0 +1,162 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import java.util.Map;
+import java.util.Set;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+public class AxStateParamsBuilder {
+ private AxReferenceKey key;
+ private AxArtifactKey trigger;
+ private Map<String, AxStateOutput> stateOutputs;
+ private Set<AxArtifactKey> contextAlbumReferenceSet;
+ private AxTaskSelectionLogic taskSelectionLogic;
+ private Map<String, AxStateFinalizerLogic> stateFinalizerLogicMap;
+ private AxArtifactKey defaultTask;
+ private Map<AxArtifactKey, AxStateTaskReference> taskReferenceMap;
+
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ public AxArtifactKey getTrigger() {
+ return trigger;
+ }
+
+ public Map<String, AxStateOutput> getStateOutputs() {
+ return stateOutputs;
+ }
+
+ public Set<AxArtifactKey> getContextAlbumReferenceSet() {
+ return contextAlbumReferenceSet;
+ }
+
+ public AxTaskSelectionLogic getTaskSelectionLogic() {
+ return taskSelectionLogic;
+ }
+
+ public Map<String, AxStateFinalizerLogic> getStateFinalizerLogicMap() {
+ return stateFinalizerLogicMap;
+ }
+
+ public AxArtifactKey getDefaultTask() {
+ return defaultTask;
+ }
+
+ public Map<AxArtifactKey, AxStateTaskReference> getTaskReferenceMap() {
+ return taskReferenceMap;
+ }
+
+ /**
+ * Setter method.
+ *
+ * @param key the reference key of the state
+ * @return builder object
+ */
+ public AxStateParamsBuilder key(AxReferenceKey key) {
+ this.key = key;
+ return this;
+ }
+
+ /**
+ * Setter method.
+ *
+ * @param trigger the event that triggers the state
+ * @return builder object
+ */
+ public AxStateParamsBuilder trigger(AxArtifactKey trigger) {
+ this.trigger = trigger;
+ return this;
+ }
+
+ /**
+ * Setter method.
+ *
+ * @param stateOutputs the possible state outputs for the state
+ * @return builder object
+ */
+ public AxStateParamsBuilder stateOutputs(Map<String, AxStateOutput> stateOutputs) {
+ this.stateOutputs = stateOutputs;
+ return this;
+ }
+
+ /**
+ * Setter method.
+ *
+ * @param contextAlbumReferenceSet the context album reference set defines the context that may
+ * be used by Task Selection Logic and State Finalizer Logic in the state
+ * @return builder object
+ */
+ public AxStateParamsBuilder contextAlbumReferenceSet(Set<AxArtifactKey> contextAlbumReferenceSet) {
+ this.contextAlbumReferenceSet = contextAlbumReferenceSet;
+ return this;
+ }
+
+ /**
+ * Setter method.
+ *
+ * @param taskSelectionLogic the task selection logic that selects the task a state executes in
+ * an execution cycle
+ * @return builder object
+ */
+ public AxStateParamsBuilder taskSelectionLogic(AxTaskSelectionLogic taskSelectionLogic) {
+ this.taskSelectionLogic = taskSelectionLogic;
+ return this;
+ }
+
+ /**
+ * Setter method.
+ *
+ * @param stateFinalizerLogicMap the state finalizer logic instances that selects the state
+ * output to use after a task executes in a state execution cycle
+ * @return builder object
+ */
+ public AxStateParamsBuilder stateFinalizerLogicMap(
+ Map<String, AxStateFinalizerLogic> stateFinalizerLogicMap) {
+ this.stateFinalizerLogicMap = stateFinalizerLogicMap;
+ return this;
+ }
+
+ /**
+ * Setter method.
+ *
+ * @param defaultTask the default task that will execute in a state if Task Selection Logic is
+ * not specified
+ * @return builder object
+ */
+ public AxStateParamsBuilder defaultTask(AxArtifactKey defaultTask) {
+ this.defaultTask = defaultTask;
+ return this;
+ }
+
+ /**
+ * Setter method.
+ *
+ * @param taskReferenceMap the task reference map that defines the tasks for the state and how
+ * @return builder object
+ */
+ public AxStateParamsBuilder taskReferenceMap(Map<AxArtifactKey, AxStateTaskReference> taskReferenceMap) {
+ this.taskReferenceMap = taskReferenceMap;
+ return this;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskOutputType.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskOutputType.java
new file mode 100644
index 000000000..171747c0c
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskOutputType.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.policymodel.concepts;
+
+/**
+ * This enumeration defines the type of state output selection that is defined for a task in a
+ * state. The {@link AxStateTaskReference} instance for each task uses this enumeration to decide
+ * what type of output selection to use when a task has completed execution.
+ */
+public enum AxStateTaskOutputType {
+ /** The state output selection for the task has not been defined. */
+ UNDEFINED,
+ /**
+ * Direct state output selection has been selected, the task will select a {@link AxStateOutput}
+ * directly.
+ */
+ DIRECT,
+ /**
+ * Logic state output selection has been selected, the task will select a {@link AxStateOutput}
+ * using logic defined in a {@link AxStateFinalizerLogic} instance.
+ */
+ LOGIC
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java
new file mode 100644
index 000000000..748eca92d
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java
@@ -0,0 +1,339 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class defines the type of output handling that will be used when a task in a state completes
+ * execution. Each task {@link AxTask} in a state {@link AxState} must select a state output
+ * {@link AxStateOutput} in order to pass its fields to an output event. Therefore, each task has an
+ * associated instance of this class that defines how the state output of the state is selected and
+ * how the output fields of the task are marshaled onto the fields of the output event. A
+ * {@link AxStateTaskReference} instance defines the task output handling as either
+ * {@link AxStateTaskOutputType#DIRECT} or {@link AxStateTaskOutputType#LOGIC}. In the case of
+ * {@link AxStateTaskOutputType#DIRECT} output selection, the output reference key held in this
+ * {@link AxStateTaskReference} instance to an instance of an {@link AxStateOutput} class. In the
+ * case of {@link AxStateTaskOutputType#LOGIC} output selection, the output reference key held in
+ * this {@link AxStateTaskReference} instance to an instance of an {@link AxStateFinalizerLogic}
+ * class. See the explanation in the {@link AxState} class for a full description of this handling.
+ *
+ * <p>During validation of a state task reference, the validation checks listed below are executed:
+ * <ol>
+ * <li>The state task reference key must not be a null key and must be valid, see validation in
+ * {@link AxReferenceKey}
+ * <li>The output type must be defined, that is not equal to {@link AxStateTaskOutputType#UNDEFINED}
+ * <li>The output key must not be a null key and must be valid, see validation in
+ * {@link AxReferenceKey}
+ * </ol>
+ */
+public class AxStateTaskReference extends AxConcept {
+ private static final long serialVersionUID = 8041771382337655535L;
+
+ private AxReferenceKey key;
+ private AxStateTaskOutputType outputType;
+ private AxReferenceKey output;
+
+ /**
+ * The Default Constructor creates a state task reference with a null reference key, an
+ * undefined output type and a null output reference key.
+ */
+ public AxStateTaskReference() {
+ this(new AxReferenceKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxStateTaskReference(final AxStateTaskReference copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a state task reference with the given reference key, an
+ * undefined output type and a null output reference key.
+ *
+ * @param key the key
+ */
+ public AxStateTaskReference(final AxReferenceKey key) {
+ this(key, // Key
+ AxStateTaskOutputType.UNDEFINED, // Output type
+ AxReferenceKey.getNullKey()); // Output
+ }
+
+ /**
+ * This Constructor creates a state task reference instance with a reference key composed from
+ * the given parent key with a local name composed by concatenating the name of the task key
+ * with the local name of the output. The output type and output are set to the given values.
+ *
+ * @param parentKey the parent key to use for the key of the state task reference
+ * @param taskKey the task key to use for the first part of the state task reference local name
+ * @param outputType the type of output to perform when this state task reference instance is
+ * used
+ * @param output the output to perform when this state task reference instance is used
+ */
+ public AxStateTaskReference(final AxReferenceKey parentKey, final AxArtifactKey taskKey,
+ final AxStateTaskOutputType outputType, final AxReferenceKey output) {
+ this(new AxReferenceKey(parentKey, taskKey.getName() + '_' + outputType.name() + '_' + output.getLocalName()),
+ outputType, output);
+ }
+
+ /**
+ * This Constructor creates a state task reference instance with the given reference key and all
+ * its fields defined.
+ *
+ * @param key the key of the state task reference
+ * @param outputType the type of output to perform when this state task reference instance is
+ * used
+ * @param output the output to perform when this state task reference instance is used
+ */
+ public AxStateTaskReference(final AxReferenceKey key, final AxStateTaskOutputType outputType,
+ final AxReferenceKey output) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(outputType, "outputType may not be null");
+ Assertions.argumentNotNull(output, "output may not be null");
+
+ this.key = key;
+ this.outputType = outputType;
+ this.output = output;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ if (!output.equals(AxReferenceKey.getNullKey())) {
+ keyList.add(new AxKeyUse(output));
+ }
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the state task reference.
+ *
+ * @param key the key of the state task reference
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the type of output to perform when this state task reference instance is used.
+ *
+ * @return the the type of output to perform when this state task reference instance is used
+ */
+ public AxStateTaskOutputType getStateTaskOutputType() {
+ return outputType;
+ }
+
+ /**
+ * Sets the type of output to perform when this state task reference instance is used.
+ *
+ * @param stateTaskOutputType the type of output to perform when this state task reference
+ * instance is used
+ */
+ public void setStateTaskOutputType(final AxStateTaskOutputType stateTaskOutputType) {
+ Assertions.argumentNotNull(stateTaskOutputType, "outputType may not be null");
+ this.outputType = stateTaskOutputType;
+ }
+
+ /**
+ * Gets the output to perform when this state task reference instance is used.
+ *
+ * @return the output to perform when this state task reference instance is used
+ */
+ public AxReferenceKey getOutput() {
+ return output;
+ }
+
+ /**
+ * Sets the output to perform when this state task reference instance is used.
+ *
+ * @param output the output to perform when this state task reference instance is used
+ */
+ public void setOutput(final AxReferenceKey output) {
+ Assertions.argumentNotNull(output, "output may not be null");
+ this.output = output;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (outputType == AxStateTaskOutputType.UNDEFINED) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "outputType may not be UNDEFINED"));
+ }
+
+ if (output.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "output key " + output.getId() + " is a null key"));
+ }
+ result = output.validate(result);
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ output.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("stateKey=");
+ builder.append(key);
+ builder.append(",outputType=");
+ builder.append(outputType);
+ builder.append(",output=");
+ builder.append(output);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxStateTaskReference.class);
+
+ final AxStateTaskReference copy = ((AxStateTaskReference) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setStateTaskOutputType(AxStateTaskOutputType.valueOf(outputType.name()));
+ copy.setOutput(output);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + outputType.hashCode();
+ result = prime * result + output.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxStateTaskReference other = (AxStateTaskReference) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (outputType != other.outputType) {
+ return false;
+ }
+ return output.equals(other.output);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxStateTaskReference other = (AxStateTaskReference) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!outputType.equals(other.outputType)) {
+ return outputType.compareTo(other.outputType);
+ }
+ return output.compareTo(other.output);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java
new file mode 100644
index 000000000..a27e1af1e
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java
@@ -0,0 +1,173 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import lombok.EqualsAndHashCode;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * The Class is used to return the tree that represents the state branches or chains in a policy. It
+ * creates a tree that holds the state fan out branches in a policy that starts from the given top
+ * state of the tree. Each branch from a state is held in a set of next states for the top state and
+ * each branch in the state tree is itself a {@link AxStateTree} instance.
+ *
+ * <p>Validation checks for recursive state use, in other words validation forbids the use of a given
+ * state more than once in a state tree.
+ */
+@EqualsAndHashCode
+public class AxStateTree implements Comparable<AxStateTree> {
+ private final AxState thisState;
+ private final Set<AxStateTree> nextStates;
+
+ /**
+ * This constructor recursively creates a state tree for the given policy starting at the given
+ * state.
+ *
+ * @param policy the policy from which to read states
+ * @param thisState the state to start state tree construction at
+ * @param referencedStateNameSet a set of state names already referenced in the tree, null for
+ * the first recursive call
+ */
+ public AxStateTree(final AxPolicy policy, final AxState thisState, Set<AxReferenceKey> referencedStateNameSet) {
+ Assertions.argumentNotNull(policy, "policy may not be null");
+ Assertions.argumentNotNull(thisState, "thisState may not be null");
+
+ this.thisState = thisState;
+ nextStates = new TreeSet<>();
+
+ for (final AxStateOutput stateOutput : thisState.getStateOutputs().values()) {
+ final AxState nextState = policy.getStateMap().get(stateOutput.getNextState().getLocalName());
+
+ // Check for end of state branch
+ if (stateOutput.getNextState().equals(AxReferenceKey.getNullKey())) {
+ continue;
+ }
+
+ if (referencedStateNameSet == null) {
+ referencedStateNameSet = new LinkedHashSet<>();
+ referencedStateNameSet.add(thisState.getKey());
+ }
+
+ // Check for state tree loops
+ if (referencedStateNameSet.contains(nextState.getKey())) {
+ throw new PolicyRuntimeException("loop detected in state tree for policy " + policy.getId() + " state "
+ + thisState.getKey().getLocalName() + ", next state " + nextState.getKey().getLocalName()
+ + " referenced more than once");
+ }
+ referencedStateNameSet.add(stateOutput.getNextState());
+ nextStates.add(new AxStateTree(policy, nextState, referencedStateNameSet));
+ }
+ }
+
+ /**
+ * Gets the state for this state tree node.
+ *
+ * @return the state
+ */
+ public AxState getState() {
+ return thisState;
+ }
+
+ /**
+ * Gets the next states for this state tree node.
+ *
+ * @return the next states
+ */
+ public Set<AxStateTree> getNextStates() {
+ return nextStates;
+ }
+
+ /**
+ * Gets the list of states referenced by this state tree as a list.
+ *
+ * @return the list of states referenced
+ */
+ public List<AxState> getReferencedStateList() {
+ final List<AxState> referencedStateList = new ArrayList<>();
+
+ referencedStateList.add(thisState);
+ for (final AxStateTree nextStateTree : nextStates) {
+ referencedStateList.addAll(nextStateTree.getReferencedStateList());
+ }
+
+ return referencedStateList;
+ }
+
+ /**
+ * Gets the list of states referenced by this state tree as a set.
+ *
+ * @return the set of states referenced
+ */
+ public Set<AxState> getReferencedStateSet() {
+ final Set<AxState> referencedStateSet = new TreeSet<>();
+
+ referencedStateSet.add(thisState);
+ for (final AxStateTree nextStateTree : nextStates) {
+ referencedStateSet.addAll(nextStateTree.getReferencedStateSet());
+ }
+
+ return referencedStateSet;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxStateTree otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+
+ final AxStateTree other = otherObj;
+ int result = thisState.compareTo(other.thisState);
+ if (result != 0) {
+ return result;
+ }
+
+ result = Integer.compare(nextStates.size(), other.nextStates.size());
+ if (result != 0) {
+ return result;
+ }
+
+ Iterator<AxStateTree> iter1 = nextStates.iterator();
+ Iterator<AxStateTree> iter2 = other.nextStates.iterator();
+
+ while (iter1.hasNext()) {
+ result = iter1.next().compareTo(iter2.next());
+ if (result != 0) {
+ return result;
+ }
+ }
+
+ return 0;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTask.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTask.java
new file mode 100644
index 000000000..c8b6baf4b
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTask.java
@@ -0,0 +1,405 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import com.google.gson.annotations.SerializedName;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.Setter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class holds the definition of a task in Apex. A task is executed by a state and performs
+ * some domain specific logic to carry out work required to be done by a policy. The Task Logic that
+ * is executed by a task is held in a {@link AxTaskLogic} instance.
+ *
+ * <p>A task has a set of input fields and output fields, which are passed to and are emitted from the
+ * task during a task execution cycle. A task may have task parameters {@link AxTaskParameter},
+ * which are configuration values passed to a task at initialization time.
+ *
+ * <p>The Task Logic in a task may use information in context albums to perform their domain specific
+ * work. The context albums that the task uses and that should be made available to the task by Apex
+ * policy distribution are held as a set of references to context albums in the task.
+ *
+ * <p>During validation of a task, the validation checks listed below are executed:
+ * <ol>
+ * <li>The task key must not be a null key and must be valid, see validation in
+ * {@link AxArtifactKey}
+ * <li>The parent of each task parameter of a task must be that task
+ * <li>Each task parameter must be valid, see validation in {@link AxTaskParameter}
+ * <li>The parent of the task logic in a task must be that task
+ * <li>The task logic must be valid, see validation in {@link AxTaskLogic}
+ * </ol>
+ */
+@Getter
+@Setter
+public class AxTask extends AxConcept {
+ private static final String DOES_NOT_EQUAL_TASK_KEY = " does not equal task key";
+
+ private static final long serialVersionUID = 5374237330697362762L;
+
+ @NonNull
+ private AxArtifactKey key;
+
+ private AxEvent inputEvent;
+ private Map<String, AxEvent> outputEvents;
+ private Map<String, AxTaskParameter> taskParameters;
+
+ @SerializedName("contextAlbumReference")
+ @NonNull
+ private Set<AxArtifactKey> contextAlbumReferenceSet;
+
+ @NonNull
+ private AxTaskLogic taskLogic;
+
+ /**
+ * The Default Constructor creates a task with a null key no input or output fields, no task
+ * parameters, no context album references and no logic.
+ */
+ public AxTask() {
+ this(new AxArtifactKey());
+ contextAlbumReferenceSet = new TreeSet<>();
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxTask(final AxTask copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a task with the given key no input or output fields, no task
+ * parameters, no context album references and no logic.
+ *
+ * @param key the key of the task
+ */
+ public AxTask(final AxArtifactKey key) {
+ this(key, // Task Key
+ new TreeMap<>(), // Task Parameters
+ new TreeSet<>(), // Context Album References
+ new AxTaskLogic(new AxReferenceKey(key)) // Task Logic
+ );
+ }
+
+ /**
+ * This Constructor defines all the fields of the task.
+ *
+ * @param key the key of the task
+ * @param taskParameters the task parameters that are used to initialize tasks of this type
+ * @param contextAlbumReferenceSet the context album reference set defines the context that may
+ * be used by Task Logic in the state
+ * @param taskLogic the task logic that performs the domain specific work of the task
+ */
+ public AxTask(final AxArtifactKey key, final Map<String, AxTaskParameter> taskParameters,
+ final Set<AxArtifactKey> contextAlbumReferenceSet, final AxTaskLogic taskLogic) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(taskParameters, "taskParameters may not be null");
+ Assertions.argumentNotNull(contextAlbumReferenceSet, "contextAlbumReferenceSet may not be null");
+ Assertions.argumentNotNull(taskLogic, "taskLogic may not be null");
+
+ this.key = key;
+ this.taskParameters = taskParameters;
+ this.contextAlbumReferenceSet = contextAlbumReferenceSet;
+ this.taskLogic = taskLogic;
+ }
+
+ /**
+ * When a task is deserialized from disk or from the database, the parent of contained objects
+ * is not defined. This method is called by JAXB after deserialization and is used to set the
+ * parent keys of all {@link AxTaskParameter} instance in the task.
+ */
+ @Override
+ public void buildReferences() {
+ if (!taskLogic.getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ taskLogic.getKey().setParentArtifactKey(key);
+ }
+
+ taskParameters.values().stream().forEach(parameter -> parameter.getKey().setParentArtifactKey(key));
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ for (final AxTaskParameter taskParameter : taskParameters.values()) {
+ keyList.addAll(taskParameter.getKeys());
+ }
+ for (final AxArtifactKey contextAlbumKey : contextAlbumReferenceSet) {
+ keyList.add(new AxKeyUse(contextAlbumKey));
+ }
+ keyList.addAll(taskLogic.getKeys());
+ return keyList;
+ }
+
+ /**
+ * Gets the context album reference set defines the context that may be used by Task Logic in
+ * the state.
+ *
+ * @return the context album reference set defines the context that may be used by Task Logic in
+ * the state
+ */
+ public Set<AxArtifactKey> getContextAlbumReferences() {
+ return contextAlbumReferenceSet;
+ }
+
+ /**
+ * Sets the context album reference set defines the context that may be used by Task Logic in
+ * the state.
+ *
+ * @param contextAlbumReferences the context album reference set defines the context that may be
+ * used by Task Logic in the state
+ */
+ public void setContextAlbumReferences(final Set<AxArtifactKey> contextAlbumReferences) {
+ Assertions.argumentNotNull(contextAlbumReferences, "contextAlbumReferences may not be null");
+ this.contextAlbumReferenceSet = contextAlbumReferences;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ for (final Entry<String, AxTaskParameter> taskParameterEntry : taskParameters.entrySet()) {
+ result = validateTaskParameterEntry(taskParameterEntry, result);
+ }
+
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ result = validateContextAlbumReference(contextAlbumReference, result);
+ }
+
+ if (!taskLogic.getKey().getParentArtifactKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "taskLogic parent key " + taskLogic.getKey().getId() + DOES_NOT_EQUAL_TASK_KEY));
+ }
+
+ return taskLogic.validate(result);
+ }
+
+ /**
+ * Validate a task parameter entry.
+ *
+ * @param taskParameterEntry the task parameter entry to validate
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult validateTaskParameterEntry(final Entry<String, AxTaskParameter> taskParameterEntry,
+ AxValidationResult result) {
+ if (taskParameterEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null input task parameter value found on task parameter " + taskParameterEntry.getKey()));
+ } else {
+ if (!taskParameterEntry.getValue().getKey().getParentArtifactKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent key on task parameter " + taskParameterEntry.getKey() + DOES_NOT_EQUAL_TASK_KEY));
+ }
+
+ result = taskParameterEntry.getValue().validate(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate a context album reference entry.
+ *
+ * @param contextAlbumReference the context album reference entry to validate
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult validateContextAlbumReference(final AxArtifactKey contextAlbumReference,
+ AxValidationResult result) {
+ if (contextAlbumReference.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on context item reference entry " + contextAlbumReference.getKey()
+ + " may not be the null key"));
+ }
+
+ return contextAlbumReference.validate(result);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final AxTaskParameter parameter : taskParameters.values()) {
+ parameter.clean();
+ }
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ contextAlbumReference.clean();
+ }
+ taskLogic.clean();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",taskParameters=");
+ builder.append(taskParameters);
+ builder.append(",contextAlbumReferenceSet=");
+ builder.append(contextAlbumReferenceSet);
+ builder.append(",taskLogic=");
+ builder.append(taskLogic);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxTask.class);
+
+ final AxTask copy = ((AxTask) copyObject);
+ copy.setKey(key);
+
+ final Map<String, AxTaskParameter> newTaskParameter = new TreeMap<>();
+ for (final Entry<String, AxTaskParameter> taskParameterEntry : taskParameters.entrySet()) {
+ newTaskParameter.put(taskParameterEntry.getKey(), new AxTaskParameter(taskParameterEntry.getValue()));
+ }
+ copy.setTaskParameters(newTaskParameter);
+
+ final Set<AxArtifactKey> newContextUsage = new TreeSet<>();
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ newContextUsage.add(new AxArtifactKey(contextAlbumReference));
+ }
+ copy.setContextAlbumReferences(newContextUsage);
+
+ copy.setTaskLogic(new AxTaskLogic(taskLogic));
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + taskParameters.hashCode();
+ result = prime * result + contextAlbumReferenceSet.hashCode();
+ result = prime * result + taskLogic.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxTask other = (AxTask) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!taskParameters.equals(other.taskParameters)) {
+ return false;
+ }
+ if (!contextAlbumReferenceSet.equals(other.contextAlbumReferenceSet)) {
+ return false;
+ }
+ return taskLogic.equals(other.taskLogic);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxTask other = (AxTask) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!taskParameters.equals(other.taskParameters)) {
+ return (taskParameters.hashCode() - other.taskParameters.hashCode());
+ }
+ if (!contextAlbumReferenceSet.equals(other.contextAlbumReferenceSet)) {
+ return (contextAlbumReferenceSet.hashCode() - other.contextAlbumReferenceSet.hashCode());
+ }
+ return taskLogic.compareTo(other.taskLogic);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskLogic.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskLogic.java
new file mode 100644
index 000000000..8665d9e3e
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskLogic.java
@@ -0,0 +1,120 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.policymodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+/**
+ * This class holds Task Logic for {@link AxTask} tasks in Apex. It is a specialization of the
+ * {@link AxLogic} class, so that Task Logic in Apex states can be strongly typed.
+ *
+ * <p>Task Logic is used to execute tasks {@link AxTask} in Apex. The logic uses fields on the incoming
+ * trigger event and information from the context albums available on a task to get context during
+ * execution. The task logic populates the output fields of the task.
+ *
+ * <p>Validation uses standard Apex Logic validation, see validation in {@link AxLogic}.
+ */
+public class AxTaskLogic extends AxLogic {
+ private static final long serialVersionUID = 2090324845463750391L;
+
+ /**
+ * The Default Constructor creates a logic instance with a null key, undefined logic flavour and
+ * a null logic string.
+ */
+ public AxTaskLogic() {
+ super();
+ }
+
+ /**
+ * The Key Constructor creates a logic instance with the given reference key, undefined logic
+ * flavour and a null logic string.
+ *
+ * @param key the reference key of the logic
+ */
+ public AxTaskLogic(final AxReferenceKey key) {
+ super(key, LOGIC_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name and all of its fields defined.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxTaskLogic(final AxArtifactKey parentKey, final String logicName, final String logicFlavour,
+ final String logic) {
+ super(new AxReferenceKey(parentKey, logicName), logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and all of its fields
+ * defined.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxTaskLogic(final AxReferenceKey key, final String logicFlavour, final String logic) {
+ super(key, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance by cloning the fields from another logic instance
+ * into this logic instance.
+ *
+ * @param logic the logic instance to clone from
+ */
+ public AxTaskLogic(final AxLogic logic) {
+ super(new AxReferenceKey(logic.getKey()), logic.getLogicFlavour(), logic.getLogic());
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name, the given logic flavour, with the logic being provided by the
+ * given logic reader instance.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxTaskLogic(final AxArtifactKey parentKey, final String logicName, final String logicFlavour,
+ final AxLogicReader logicReader) {
+ super(new AxReferenceKey(parentKey, logicName), logicFlavour, logicReader);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and logic flavour, the
+ * logic is provided by the given logic reader instance.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxTaskLogic(final AxReferenceKey key, final String logicFlavour, final AxLogicReader logicReader) {
+ super(key, logicFlavour, logicReader);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskParameter.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskParameter.java
new file mode 100644
index 000000000..a468ec499
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskParameter.java
@@ -0,0 +1,253 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019,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.onap.policy.apex.model.policymodel.concepts;
+
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is used to specify the configuration parameters that may be passed to a task
+ * {@link AxTask}. Task parameters are read from a configuration file when Apex starts and are
+ * passed to the task by the Apex engine when a task is executed. Each task parameter has a key and
+ * a default value. If the task parameter is not set in a configuration file, the task uses its
+ * default value.
+ */
+public class AxTaskParameter extends AxConcept {
+ private static final long serialVersionUID = 7351688156934099977L;
+
+ private AxReferenceKey key;
+ private String defaultValue;
+
+ /**
+ * The Default Constructor creates a task parameter with a null reference key and a null default
+ * value.
+ */
+ public AxTaskParameter() {
+ this(new AxReferenceKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxTaskParameter(final AxTaskParameter copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a task parameter with the given reference key and a null
+ * default value.
+ *
+ * @param taskParameterKey the task parameter key
+ */
+ public AxTaskParameter(final AxReferenceKey taskParameterKey) {
+ this(taskParameterKey, "");
+ }
+
+ /**
+ * The Default Constructor creates a task parameter with the given reference key and default
+ * value.
+ *
+ * @param key the reference key of the task parameter
+ * @param defaultValue the default value of the task parameter
+ */
+ public AxTaskParameter(final AxReferenceKey key, final String defaultValue) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(defaultValue, "defaultValue may not be null");
+
+ this.key = key;
+ this.defaultValue = defaultValue.trim();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return key.getKeys();
+ }
+
+ /**
+ * Sets the reference key of the task parameter.
+ *
+ * @param key the reference key of the task parameter
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the default value of the task parameter.
+ *
+ * @return the default value of the task parameter
+ */
+ public String getTaskParameterValue() {
+ return defaultValue;
+ }
+
+ /**
+ * Sets the default value of the task parameter.
+ *
+ * @param defaultValue the default value of the task parameter
+ */
+ public void setDefaultValue(final String defaultValue) {
+ Assertions.argumentNotNull(defaultValue, "defaultValue may not be null");
+ this.defaultValue = defaultValue.trim();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (defaultValue.trim().length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.WARNING,
+ "no defaultValue specified, defaultValue is blank"));
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ defaultValue = defaultValue.trim();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",defaultValue=");
+ builder.append(defaultValue);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxTaskParameter.class);
+
+ final AxTaskParameter copy = ((AxTaskParameter) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setDefaultValue(defaultValue);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + defaultValue.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxTaskParameter other = (AxTaskParameter) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return defaultValue.equals(other.defaultValue);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxTaskParameter other = (AxTaskParameter) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ return defaultValue.compareTo(other.defaultValue);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskSelectionLogic.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskSelectionLogic.java
new file mode 100644
index 000000000..b9cfd802d
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskSelectionLogic.java
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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.onap.policy.apex.model.policymodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+/**
+ * This class holds Task Selection Logic for {@link AxState} states in Apex. It is a specialization
+ * of the {@link AxLogic} class, so that Task Selection Logic in Apex states can be strongly typed.
+ *
+ * <p>Task Selection Logic is used to select the task {@link AxTask} that a state will execute. The
+ * logic uses fields on the incoming trigger event and information from the context albums available
+ * on a state to decide what task {@link AxTask} to select for execution in a given context.
+ *
+ * <p>Validation uses standard Apex Logic validation, see validation in {@link AxLogic}.
+ */
+public class AxTaskSelectionLogic extends AxLogic {
+ private static final long serialVersionUID = 2090324845463750391L;
+
+ /**
+ * The Default Constructor creates a logic instance with a null key, undefined logic flavour and
+ * a null logic string.
+ */
+ public AxTaskSelectionLogic() {
+ super();
+ }
+
+ /**
+ * The Key Constructor creates a logic instance with the given reference key, undefined logic
+ * flavour and a null logic string.
+ *
+ * @param key the reference key of the logic
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey key) {
+ super(key, LOGIC_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name and all of its fields defined.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final String logic) {
+ super(parentKey, logicName, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and all of its fields
+ * defined.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey key, final String logicFlavour, final String logic) {
+ super(key, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance by cloning the fields from another logic instance
+ * into this logic instance.
+ *
+ * @param logic the logic instance to clone from
+ */
+ public AxTaskSelectionLogic(final AxLogic logic) {
+ super(new AxReferenceKey(logic.getKey()), logic.getLogicFlavour(), logic.getLogic());
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name, the given logic flavour, with the logic being provided by the
+ * given logic reader instance.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final AxLogicReader logicReader) {
+ super(new AxReferenceKey(parentKey, logicName), logicFlavour, logicReader);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and logic flavour, the
+ * logic is provided by the given logic reader instance.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey key, final String logicFlavour, final AxLogicReader logicReader) {
+ super(key, logicFlavour, logicReader);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTasks.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTasks.java
new file mode 100644
index 000000000..f9ccafd54
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTasks.java
@@ -0,0 +1,351 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,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.onap.policy.apex.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is a task container and holds a map of the tasks for an entire Apex model. All Apex
+ * models that use tasks must have an {@link AxTasks} field. The {@link AxTasks} class implements
+ * the helper methods of the {@link AxConceptGetter} interface to allow {@link AxTask} instances to
+ * be retrieved by calling methods directly on this class without referencing the contained map.
+ *
+ * <p>Validation checks that the container key is not null. An error is issued if no tasks are defined
+ * in the container. Each task entry is checked to ensure that its key and value are not null and
+ * that the key matches the key in the map value. Each task entry is then validated individually.
+ */
+public class AxTasks extends AxConcept implements AxConceptGetter<AxTask> {
+ private static final long serialVersionUID = 4290442590545820316L;
+
+ private AxArtifactKey key;
+ private Map<AxArtifactKey, AxTask> taskMap;
+
+ /**
+ * The Default Constructor creates a {@link AxTasks} object with a null artifact key and creates
+ * an empty event map.
+ */
+ public AxTasks() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxTasks(final AxTasks copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a {@link AxTasks} object with the given artifact key and
+ * creates an empty event map.
+ *
+ * @param key the key
+ */
+ public AxTasks(final AxArtifactKey key) {
+ this(key, new TreeMap<>());
+ }
+
+ /**
+ * This Constructor creates a task container with all of its fields defined.
+ *
+ * @param key the task container key
+ * @param taskMap the tasks to be stored in the task container
+ */
+ public AxTasks(final AxArtifactKey key, final Map<AxArtifactKey, AxTask> taskMap) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(taskMap, "taskMap may not be null");
+
+ this.key = key;
+ this.taskMap = new TreeMap<>();
+ this.taskMap.putAll(taskMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ for (final AxTask task : taskMap.values()) {
+ keyList.addAll(task.getKeys());
+ }
+
+ return keyList;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void buildReferences() {
+ taskMap.values().stream().forEach(task -> task.buildReferences());
+ }
+
+ /**
+ * Sets the task container key.
+ *
+ * @param key the task container key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the tasks stored in the task container.
+ *
+ * @return the tasks stored in the task container
+ */
+ public Map<AxArtifactKey, AxTask> getTaskMap() {
+ return taskMap;
+ }
+
+ /**
+ * Sets the tasks to be stored in the task container.
+ *
+ * @param taskMap the tasks to be stored in the task container
+ */
+ public void setTaskMap(final Map<AxArtifactKey, AxTask> taskMap) {
+ Assertions.argumentNotNull(taskMap, "taskMap may not be null");
+ this.taskMap = new TreeMap<>();
+ this.taskMap.putAll(taskMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (taskMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "taskMap may not be empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxTask> taskEntry : taskMap.entrySet()) {
+ if (taskEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on task entry " + taskEntry.getKey() + " may not be the null key"));
+ } else if (taskEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on task entry " + taskEntry.getKey() + " may not be null"));
+ } else {
+ if (!taskEntry.getKey().equals(taskEntry.getValue().getKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(),
+ ValidationResult.INVALID, "key on task entry key " + taskEntry.getKey()
+ + " does not equal task value key " + taskEntry.getValue().getKey()));
+ }
+
+ result = taskEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxTask> taskEntry : taskMap.entrySet()) {
+ taskEntry.getKey().clean();
+ taskEntry.getValue().clean();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",taskMap=");
+ builder.append(taskMap);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxTasks.class);
+
+ final AxTasks copy = ((AxTasks) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+
+ final Map<AxArtifactKey, AxTask> newTaskMap = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxTask> taskMapEntry : taskMap.entrySet()) {
+ newTaskMap.put(new AxArtifactKey(taskMapEntry.getKey()), new AxTask(taskMapEntry.getValue()));
+ }
+ copy.setTaskMap(newTaskMap);
+
+ return copy;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + taskMap.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxTasks other = (AxTasks) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return taskMap.equals(other.taskMap);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxTasks other = (AxTasks) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!taskMap.equals(other.taskMap)) {
+ return (taskMap.hashCode() - other.taskMap.hashCode());
+ }
+
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxTask get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).get(conceptKey);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxTask get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).get(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxTask get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxTask> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).getAll(conceptKeyName);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<AxTask> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyException.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyException.java
new file mode 100644
index 000000000..271e0c2af
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+
+/**
+ * This exception is raised if an error occurs in an Apex policy or in Apex policy handling.
+ *
+ * @author Liam Fallon
+ */
+public class PolicyException extends ApexException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ /**
+ * Instantiates a new apex policy exception with a message.
+ *
+ * @param message the message
+ */
+ public PolicyException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new apex policy exception with a message and a caused by exception.
+ *
+ * @param message the message
+ * @param exception the exception that caused this exception to be thrown
+ */
+ public PolicyException(final String message, final Exception exception) {
+ super(message, exception);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyRuntimeException.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyRuntimeException.java
new file mode 100644
index 000000000..7ad293187
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyRuntimeException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
+
+/**
+ * This exception is raised if a runtime error occurs in an Apex policy or in Apex policy handling.
+ *
+ * @author Liam Fallon
+ */
+public class PolicyRuntimeException extends ApexRuntimeException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ /**
+ * Instantiates a new apex policy runtime exception with a message.
+ *
+ * @param message the message
+ */
+ public PolicyRuntimeException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new apex policy runtime exception with a message and a caused by exception.
+ *
+ * @param message the message
+ * @param exception the exception that caused this exception to be thrown
+ */
+ public PolicyRuntimeException(final String message, final Exception exception) {
+ super(message, exception);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/package-info.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/package-info.java
new file mode 100644
index 000000000..acf0e8221
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications 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=========================================================
+ */
+
+/**
+ * Contains the concepts required to specify policies and tasks in APEX. It defines the main Apex
+ * concepts of policies and tasks.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.policymodel.concepts;
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyser.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyser.java
new file mode 100644
index 000000000..6731caf30
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyser.java
@@ -0,0 +1,178 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import java.util.Map.Entry;
+import java.util.Set;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxState;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class analyses a policy model and shows what the usage of each context album, context item, data type, and event
+ * is.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyAnalyser {
+ /**
+ * Perform an analysis on a policy model.
+ *
+ * @param policyModel The policy model
+ * @return the analysis result of the policy model
+ */
+ public PolicyAnalysisResult analyse(final AxPolicyModel policyModel) {
+ Assertions.argumentNotNull(policyModel, "policyModel may not be null");
+
+ final PolicyAnalysisResult result = new PolicyAnalysisResult(policyModel);
+
+ for (final AxPolicy policy : policyModel.getPolicies().getPolicyMap().values()) {
+ for (final AxState state : policy.getStateMap().values()) {
+ analyseState(state, result);
+ }
+ }
+
+ for (final AxTask task : policyModel.getTasks().getTaskMap().values()) {
+ analyseTask(task, result);
+ }
+
+ for (final AxEvent event : policyModel.getEvents().getEventMap().values()) {
+ analyseEvent(event, result);
+ }
+
+ for (final AxContextAlbum contextAlbum : policyModel.getAlbums().getAll(null)) {
+ result.getContextSchemaUsage().get(contextAlbum.getItemSchema()).add(contextAlbum.getKey());
+ }
+
+ return result;
+ }
+
+ /**
+ * Perform an analysis on a single policy in a policy model.
+ *
+ * @param policyModel The policy model
+ * @param policy The policy
+ * @return the analysis result of the policy model
+ */
+ public PolicyAnalysisResult analyse(final AxPolicyModel policyModel, final AxPolicy policy) {
+ Assertions.argumentNotNull(policyModel, "policyModel may not be null");
+ Assertions.argumentNotNull(policy, "policy may not be null");
+
+ final PolicyAnalysisResult result = new PolicyAnalysisResult(policyModel);
+
+ for (final AxState state : policy.getStateMap().values()) {
+ analyseState(state, result);
+ }
+
+ // Only analyse tasks used by this policy
+ for (final Entry<AxArtifactKey, Set<AxKey>> taskUsageEntry : result.getTaskUsage().entrySet()) {
+ // If the usage set is empty, then we skip the task as its not used in the policy
+ if (!taskUsageEntry.getValue().isEmpty()) {
+ analyseTask(policyModel.getTasks().getTaskMap().get(taskUsageEntry.getKey()), result);
+ }
+ }
+
+ // Only analyse events used by this policy, same approach as for tasks
+ for (final Entry<AxArtifactKey, Set<AxKey>> eventUsageEntry : result.getEventUsage().entrySet()) {
+ if (!eventUsageEntry.getValue().isEmpty()) {
+ analyseEvent(policyModel.getEvents().getEventMap().get(eventUsageEntry.getKey()), result);
+ }
+ }
+
+ // Only analyse context albums used by this policy, same approach as for tasks
+ for (final Entry<AxArtifactKey, Set<AxKey>> contextAlbumUsageEntry : result.getContextAlbumUsage().entrySet()) {
+ if (!contextAlbumUsageEntry.getValue().isEmpty()) {
+ final AxContextAlbum contextAlbum = policyModel.getAlbums().get(contextAlbumUsageEntry.getKey());
+ result.getContextSchemaUsage().get(contextAlbum.getItemSchema()).add(contextAlbum.getKey());
+ }
+ }
+
+ for (final AxEvent event : policyModel.getEvents().getEventMap().values()) {
+ analyseEvent(event, result);
+ }
+
+ for (final AxContextAlbum contextAlbum : policyModel.getAlbums().getAll(null)) {
+ result.getContextSchemaUsage().get(contextAlbum.getItemSchema()).add(contextAlbum.getKey());
+ }
+
+ return result;
+ }
+
+ /**
+ * Analyse the usage of concepts by a state.
+ *
+ * @param state the state to analyse
+ * @param result the result
+ */
+ private void analyseState(final AxState state, final PolicyAnalysisResult result) {
+ // Event usage by state
+ result.getEventUsage().get(state.getTrigger()).add(state.getKey());
+ for (final AxStateOutput stateOutput : state.getStateOutputs().values()) {
+ result.getEventUsage().get(stateOutput.getOutgoingEvent()).add(state.getKey());
+ }
+
+ // State Context Usage
+ for (final AxArtifactKey contextAlbumKey : state.getContextAlbumReferences()) {
+ result.getContextAlbumUsage().get(contextAlbumKey).add(state.getKey());
+ }
+
+ // Task usage by state
+ for (final AxArtifactKey task : state.getTaskReferences().keySet()) {
+ result.getTaskUsage().get(task).add(state.getKey());
+ }
+ }
+
+ /**
+ * Analyse the usage of concepts by a task.
+ *
+ * @param task the task to analyse
+ * @param result the result
+ */
+ private void analyseTask(final AxTask task, final PolicyAnalysisResult result) {
+ // Task Context Usage
+ for (final AxArtifactKey contextAlbumKey : task.getContextAlbumReferences()) {
+ result.getContextAlbumUsage().get(contextAlbumKey).add(task.getKey());
+ }
+ }
+
+ /**
+ * Analyse the usage of concepts by an event.
+ *
+ * @param event the event to analyse
+ * @param result the result of the analysis
+ */
+ private void analyseEvent(final AxEvent event, final PolicyAnalysisResult result) {
+ // Event data type usage
+ for (final AxField eventField : event.getFields()) {
+ result.getContextSchemaUsage().get(eventField.getSchema()).add(event.getKey());
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalysisResult.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalysisResult.java
new file mode 100644
index 000000000..96bdc57d0
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalysisResult.java
@@ -0,0 +1,266 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.policymodel.handling;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+/**
+ * This class finds and holds the usage of context schemas, context albums, events, and tasks by the policies in a
+ * policy model.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyAnalysisResult {
+ // Usage of context schemas
+ private final Map<AxArtifactKey, Set<AxKey>> contextSchemaUsage = new TreeMap<>();
+
+ // Usage of context maps
+ private final Map<AxArtifactKey, Set<AxKey>> contextAlbumUsage = new TreeMap<>();
+
+ // Usage of events
+ private final Map<AxArtifactKey, Set<AxKey>> eventUsage = new TreeMap<>();
+
+ // Usage of tasks
+ private final Map<AxArtifactKey, Set<AxKey>> taskUsage = new TreeMap<>();
+
+ /**
+ * This constructor creates a {@link PolicyAnalysisResult} instance that holds maps that contain the usage of
+ * context schemas, contxt albums, events, and tasks by all policies in a policy model.
+ *
+ * @param policyModel the policy model to analyse
+ */
+ public PolicyAnalysisResult(final AxPolicyModel policyModel) {
+ for (final AxArtifactKey contextSchemaKey : policyModel.getSchemas().getSchemasMap().keySet()) {
+ contextSchemaUsage.put(contextSchemaKey, new TreeSet<>());
+ }
+
+ for (final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry : policyModel.getAlbums().getAlbumsMap()
+ .entrySet()) {
+ contextAlbumUsage.put(contextAlbumEntry.getKey(), new TreeSet<>());
+ }
+
+ for (final AxArtifactKey eventKey : policyModel.getEvents().getEventMap().keySet()) {
+ eventUsage.put(eventKey, new TreeSet<>());
+ }
+
+ for (final AxArtifactKey taskKey : policyModel.getTasks().getTaskMap().keySet()) {
+ taskUsage.put(taskKey, new TreeSet<>());
+ }
+ }
+
+ /**
+ * Gets the context schemas used by policies in the policy model.
+ *
+ * @return the context schemas used by policies in the policy model
+ */
+ public Map<AxArtifactKey, Set<AxKey>> getContextSchemaUsage() {
+ return contextSchemaUsage;
+ }
+
+ /**
+ * Gets the context albums used by policies in the policy model.
+ *
+ * @return the context albums used by policies in the policy model
+ */
+ public Map<AxArtifactKey, Set<AxKey>> getContextAlbumUsage() {
+ return contextAlbumUsage;
+ }
+
+ /**
+ * Gets the events used by policies in the policy model.
+ *
+ * @return the events used by policies in the policy model
+ */
+ public Map<AxArtifactKey, Set<AxKey>> getEventUsage() {
+ return eventUsage;
+ }
+
+ /**
+ * Gets the tasks used by policies in the policy model.
+ *
+ * @return the tasks used by policies in the policy model
+ */
+ public Map<AxArtifactKey, Set<AxKey>> getTaskUsage() {
+ return taskUsage;
+ }
+
+ /**
+ * Gets the context schemas used by policies in the policy model.
+ *
+ * @return the context schemas used by policies in the policy model
+ */
+ public Set<AxArtifactKey> getUsedContextSchemas() {
+ return getUsedKeySet(contextSchemaUsage);
+ }
+
+ /**
+ * Gets the context albums used by policies in the policy model.
+ *
+ * @return the context albums used by policies in the policy model
+ */
+ public Set<AxArtifactKey> getUsedContextAlbums() {
+ return getUsedKeySet(contextAlbumUsage);
+ }
+
+ /**
+ * Gets the events used by policies in the policy model.
+ *
+ * @return the events used by policies in the policy model
+ */
+ public Set<AxArtifactKey> getUsedEvents() {
+ return getUsedKeySet(eventUsage);
+ }
+
+ /**
+ * Gets the tasks used by policies in the policy model.
+ *
+ * @return the tasks used by policies in the policy model
+ */
+ public Set<AxArtifactKey> getUsedTasks() {
+ return getUsedKeySet(taskUsage);
+ }
+
+ /**
+ * Gets the context schemas in the policy model that were not used by any policies in the policy model.
+ *
+ * @return the unused context schemas
+ */
+ public Set<AxArtifactKey> getUnusedContextSchemas() {
+ return getUnusedKeySet(contextSchemaUsage);
+ }
+
+ /**
+ * Gets the context albums in the policy model that were not used by any policies in the policy model.
+ *
+ * @return the unused context albums
+ */
+ public Set<AxArtifactKey> getUnusedContextAlbums() {
+ return getUnusedKeySet(contextAlbumUsage);
+ }
+
+ /**
+ * Gets the events in the policy model that were not used by any policies in the policy model.
+ *
+ * @return the unused events
+ */
+ public Set<AxArtifactKey> getUnusedEvents() {
+ return getUnusedKeySet(eventUsage);
+ }
+
+ /**
+ * Gets the tasks in the policy model that were not used by any policies in the policy model.
+ *
+ * @return the unused tasks
+ */
+ public Set<AxArtifactKey> getUnusedTasks() {
+ return getUnusedKeySet(taskUsage);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+
+ builder.append(getUsageMapString("Context Schema usage", contextSchemaUsage));
+ builder.append(getUsageMapString("Context Album usage", contextAlbumUsage));
+ builder.append(getUsageMapString("Event usage", eventUsage));
+ builder.append(getUsageMapString("Task usage", taskUsage));
+
+ return builder.toString();
+ }
+
+ /**
+ * Gets the usage map string.
+ *
+ * @param header the header
+ * @param usageMap the usage map
+ * @return the usage map string
+ */
+ private String getUsageMapString(final String header, final Map<? extends AxKey, Set<AxKey>> usageMap) {
+ final StringBuilder builder = new StringBuilder();
+
+ builder.append(header);
+ builder.append('\n');
+ for (final Entry<? extends AxKey, Set<AxKey>> usageEntry : usageMap.entrySet()) {
+ builder.append(" ");
+ builder.append(usageEntry.getKey().getId());
+ if (usageEntry.getValue().isEmpty()) {
+ builder.append(" (unused)\n");
+ continue;
+ }
+
+ builder.append('\n');
+ for (final AxKey usageKey : usageEntry.getValue()) {
+ builder.append(" ");
+ builder.append(usageKey.getId());
+ builder.append("\n");
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Gets the used key set.
+ *
+ * @param usageMap the usage map
+ * @return the used key set
+ */
+ private Set<AxArtifactKey> getUsedKeySet(final Map<AxArtifactKey, Set<AxKey>> usageMap) {
+ final Set<AxArtifactKey> usedKeySet = new TreeSet<>();
+
+ for (final Entry<AxArtifactKey, Set<AxKey>> usageEntry : usageMap.entrySet()) {
+ if (!usageEntry.getValue().isEmpty()) {
+ usedKeySet.add(usageEntry.getKey());
+ }
+ }
+
+ return usedKeySet;
+ }
+
+ /**
+ * Gets the unused key set.
+ *
+ * @param usageMap the usage map
+ * @return the unused key set
+ */
+ private Set<AxArtifactKey> getUnusedKeySet(final Map<AxArtifactKey, Set<AxKey>> usageMap) {
+ final Set<AxArtifactKey> usedKeySet = new TreeSet<>();
+
+ for (final Entry<AxArtifactKey, Set<AxKey>> usageEntry : usageMap.entrySet()) {
+ if (usageEntry.getValue().isEmpty()) {
+ usedKeySet.add(usageEntry.getKey());
+ }
+ }
+
+ return usedKeySet;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyComparer.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyComparer.java
new file mode 100644
index 000000000..5a947c596
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyComparer.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicies;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference;
+
+/**
+ * This class compares the policies in two {@link AxPolicies} objects and returns the differences.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyComparer {
+ /**
+ * Compare two {@link AxPolicies} objects, comparing their policy maps one after another.
+ *
+ * @param left the left policies
+ * @param right the right policies
+ * @return the difference
+ */
+ public KeyedMapDifference<AxArtifactKey, AxPolicy> compare(final AxPolicies left, final AxPolicies right) {
+ // Find the difference between the AxPolicy objects
+ return new KeyedMapComparer<AxArtifactKey, AxPolicy>().compareMaps(left.getPolicyMap(), right.getPolicyMap());
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReader.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReader.java
new file mode 100644
index 000000000..f70068454
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReader.java
@@ -0,0 +1,142 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.policymodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.policymodel.concepts.AxLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxLogicReader;
+import org.onap.policy.apex.model.policymodel.concepts.PolicyRuntimeException;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class is used to read Task Logic and Task Selection Logic from files into a string. A
+ * {@link PolicyLogicReader} can then be used to provide the logic on a {@link AxLogic} class
+ * constructor.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyLogicReader implements AxLogicReader {
+ private static final String DOT_JAVA = ".java.";
+
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyModelSplitter.class);
+
+ // The path of the logic package
+ private String logicPackage = "";
+
+ // Flag indicating if default logic should be returned
+ private String defaultLogic;
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getLogicPackage() {
+ return logicPackage;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxLogicReader setLogicPackage(final String incomingLogicPackage) {
+ this.logicPackage = incomingLogicPackage;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getDefaultLogic() {
+ return defaultLogic;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxLogicReader setDefaultLogic(final String incomingDefaultLogic) {
+ this.defaultLogic = incomingDefaultLogic;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String readLogic(final AxLogic axLogic) {
+ // Java uses compiled logic, other executor types run scripts
+ if ("JAVA".equals(axLogic.getLogicFlavour())) {
+ // Check if we're using the default logic
+ if (defaultLogic != null) {
+ // Return the java class name for the default logic
+ return logicPackage + DOT_JAVA + defaultLogic;
+ } else {
+ // Return the java class name for the logic
+ if (axLogic.getKey().getParentLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ return logicPackage + DOT_JAVA + axLogic.getKey().getParentKeyName()
+ + axLogic.getKey().getLocalName();
+ } else {
+ return logicPackage + DOT_JAVA + axLogic.getKey().getParentKeyName()
+ + axLogic.getKey().getParentLocalName() + axLogic.getKey().getLocalName();
+ }
+ }
+ }
+ // Now, we read in the script
+
+ // Get the package name of the current package and convert dots to slashes for the file path
+ String fullLogicFilePath = logicPackage.replace(".", "/");
+
+ // Now, the logic should be in a sub directory for the logic executor type
+ fullLogicFilePath += "/" + axLogic.getLogicFlavour().toLowerCase();
+
+ // Check if we're using the default logic
+ if (defaultLogic != null) {
+ // Default logic
+ fullLogicFilePath += "/" + defaultLogic;
+ } else {
+ if (axLogic.getKey().getParentLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ fullLogicFilePath += "/" + axLogic.getKey().getParentKeyName() + axLogic.getKey().getLocalName();
+ } else {
+ fullLogicFilePath += "/" + axLogic.getKey().getParentKeyName()
+ + axLogic.getKey().getParentLocalName() + axLogic.getKey().getLocalName();
+ }
+ }
+
+ // Now get the type of executor to find the extension of the file
+ fullLogicFilePath += "." + axLogic.getLogicFlavour().toLowerCase();
+
+ final String logicString = ResourceUtils.getResourceAsString(fullLogicFilePath);
+
+ // Check if the logic was found
+ if (logicString == null || logicString.length() == 0) {
+ String errorMessage = "logic not found for logic \"" + fullLogicFilePath + "\"";
+ LOGGER.warn(errorMessage);
+ throw new PolicyRuntimeException(errorMessage);
+ }
+
+ // Return the right trimmed logic string
+ return logicString.replaceAll("\\s+$", "");
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparer.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparer.java
new file mode 100644
index 000000000..f3bbdcbcf
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparer.java
@@ -0,0 +1,268 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.utilities.comparison.KeyComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyDifference;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference;
+
+/**
+ * This class compares two policy models {@link AxPolicyModel} and holds the result of that comparison. It compares
+ * policy models on their keys, their context schema differences, their event differences, their context album
+ * differences, their task differences, their policy differences, and their key information differences.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyModelComparer {
+ // Comparison of policy model keys
+ private final KeyDifference<AxArtifactKey> policyModelsKeyDifference;
+
+ // Comparison of context schemas
+ private final KeyDifference<AxArtifactKey> contextSchemasKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxContextSchema> contextSchemaCompareResult = new KeyedMapDifference<>();
+
+ // Comparison of events
+ private final KeyDifference<AxArtifactKey> eventsKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxEvent> eventComparisonResult = new KeyedMapDifference<>();
+
+ // Comparison of context albums
+ private final KeyDifference<AxArtifactKey> contextAlbumKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxContextAlbum> contextAlbumComparisonResult = new KeyedMapDifference<>();
+
+ // Comparison of tasks
+ private final KeyDifference<AxArtifactKey> tasksKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxTask> taskComparisonResult = new KeyedMapDifference<>();
+
+ // Comparison of policies
+ private final KeyDifference<AxArtifactKey> policiesKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxPolicy> policyComparisonResult = new KeyedMapDifference<>();
+
+ // Comparison of key information
+ private final KeyDifference<AxArtifactKey> keyInformationKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxKeyInfo> keyInfoComparisonResult = new KeyedMapDifference<>();
+
+ /**
+ * The Constructor.
+ *
+ * @param left the left
+ * @param right the right
+ */
+ public PolicyModelComparer(final AxPolicyModel left, final AxPolicyModel right) {
+ // @formatter:off
+ policyModelsKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ contextSchemasKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ eventsKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ contextAlbumKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ tasksKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ policiesKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ keyInformationKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+
+ contextSchemaCompareResult = new KeyedMapComparer<AxArtifactKey, AxContextSchema>().compareMaps(
+ left.getSchemas().getSchemasMap(), right.getSchemas().getSchemasMap());
+ eventComparisonResult = new KeyedMapComparer<AxArtifactKey, AxEvent>().compareMaps(
+ left.getEvents().getEventMap(), right.getEvents().getEventMap());
+ contextAlbumComparisonResult = new KeyedMapComparer<AxArtifactKey, AxContextAlbum>().compareMaps(
+ left.getAlbums().getAlbumsMap(), right.getAlbums().getAlbumsMap());
+ taskComparisonResult = new KeyedMapComparer<AxArtifactKey, AxTask>()
+ .compareMaps(left.getTasks().getTaskMap(), right.getTasks().getTaskMap());
+ policyComparisonResult = new KeyedMapComparer<AxArtifactKey, AxPolicy>().compareMaps(
+ left.getPolicies().getPolicyMap(), right.getPolicies().getPolicyMap());
+ keyInfoComparisonResult = new KeyedMapComparer<AxArtifactKey, AxKeyInfo>().compareMaps(
+ left.getKeyInformation().getKeyInfoMap(), right.getKeyInformation().getKeyInfoMap());
+ // @formatter:on
+ }
+
+ /**
+ * Gets the difference between policy model keys on the two models.
+ *
+ * @return the difference between policy model keys
+ */
+ public KeyDifference<AxArtifactKey> getPolicyModelsKeyDifference() {
+ return policyModelsKeyDifference;
+ }
+
+ /**
+ * Gets the difference between context schema keys on the two models.
+ *
+ * @return the difference between context schema keys
+ */
+ public KeyDifference<AxArtifactKey> getContextSchemaKeyDifference() {
+ return contextSchemasKeyDifference;
+ }
+
+ /**
+ * Gets the difference between context schemas on the two models.
+ *
+ * @return the difference between context schemas
+ */
+ public KeyedMapDifference<AxArtifactKey, AxContextSchema> getContextSchemaComparisonResult() {
+ return contextSchemaCompareResult;
+ }
+
+ /**
+ * Gets the difference between event keys on the two models.
+ *
+ * @return the difference between event keys
+ */
+ public KeyDifference<AxArtifactKey> getEventKeyDifference() {
+ return eventsKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the events on the two models.
+ *
+ * @return the difference between the events
+ */
+ public KeyedMapDifference<AxArtifactKey, AxEvent> getEventComparisonResult() {
+ return eventComparisonResult;
+ }
+
+ /**
+ * Gets the difference between context album keys on the two models.
+ *
+ * @return the difference between context album keys
+ */
+ public KeyDifference<AxArtifactKey> getContextAlbumKeyDifference() {
+ return contextAlbumKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the context albums on the two models.
+ *
+ * @return the difference between the context albums
+ */
+ public KeyedMapDifference<AxArtifactKey, AxContextAlbum> getContextAlbumComparisonResult() {
+ return contextAlbumComparisonResult;
+ }
+
+ /**
+ * Gets the difference between task keys on the two models.
+ *
+ * @return the difference between task keys
+ */
+ public KeyDifference<AxArtifactKey> getTaskKeyDifference() {
+ return tasksKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the tasks on the two models.
+ *
+ * @return the difference between the tasks
+ */
+ public KeyedMapDifference<AxArtifactKey, AxTask> getTaskComparisonResult() {
+ return taskComparisonResult;
+ }
+
+ /**
+ * Gets the difference between policy keys on the two models.
+ *
+ * @return the difference between policy keys
+ */
+ public KeyDifference<AxArtifactKey> getPolicykeyDifference() {
+ return policiesKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the policies on the two models.
+ *
+ * @return the difference between the policies
+ */
+ public KeyedMapDifference<AxArtifactKey, AxPolicy> getPolicyComparisonResult() {
+ return policyComparisonResult;
+ }
+
+ /**
+ * Gets the difference between key information keys on the two models.
+ *
+ * @return the difference between key information keys
+ */
+ public KeyDifference<AxArtifactKey> getKeyInformationKeyDifference() {
+ return keyInformationKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the key information on the two models.
+ *
+ * @return the difference between the key information
+ */
+ public KeyedMapDifference<AxArtifactKey, AxKeyInfo> getKeyInfoComparisonResult() {
+ return keyInfoComparisonResult;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ return asString(true, true);
+ }
+
+ /**
+ * As string.
+ *
+ * @param diffsOnly the diffs only
+ * @param keysOnly the keys only
+ * @return the string
+ */
+ public String asString(final boolean diffsOnly, final boolean keysOnly) {
+ final StringBuilder builder = new StringBuilder();
+
+ builder.append("****** policy map differences ******\n");
+ builder.append(policyModelsKeyDifference.asString(diffsOnly));
+
+ builder.append("*** context schema differences ***\n");
+ builder.append(contextSchemasKeyDifference.asString(diffsOnly));
+ builder.append(contextSchemaCompareResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** event differences ***\n");
+ builder.append(eventsKeyDifference.asString(diffsOnly));
+ builder.append(eventComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** context album differences ***\n");
+ builder.append(contextAlbumKeyDifference.asString(diffsOnly));
+ builder.append(contextAlbumComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** task differences ***\n");
+ builder.append(tasksKeyDifference.asString(diffsOnly));
+ builder.append(taskComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** policy differences ***\n");
+ builder.append(policiesKeyDifference.asString(diffsOnly));
+ builder.append(policyComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** key information differences ***\n");
+ builder.append(keyInformationKeyDifference.asString(diffsOnly));
+ builder.append(keyInfoComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("***********************************\n");
+
+ return builder.toString();
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java
new file mode 100644
index 000000000..ae0dda814
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java
@@ -0,0 +1,183 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2020-2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * Helper class used to merge information from two policy models together into a single policy
+ * model.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class PolicyModelMerger {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyModelMerger.class);
+
+ /**
+ * Private constructor used to prevent sub class instantiation.
+ */
+ private PolicyModelMerger() {
+ }
+
+ /**
+ * Get a merged policy model with information from two policy models merged into a larger policy
+ * model.
+ *
+ * @param leftPolicyModel the source Apex Model
+ * @param rightPolicyModel the policies to include in sub policy model
+ * @param useLeftOnMatches if true, uses concepts from the left model if concepts with common
+ * keys are found, if false it uses the concepts from the right model
+ * @param failOnDuplicateKeys whether to fail or not on the occurence of duplicate concept keys
+ * @return the new Destination Model
+ * @throws ApexModelException on model transfer errors
+ */
+ public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel,
+ final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches, final boolean failOnDuplicateKeys)
+ throws ApexModelException {
+ return getMergedPolicyModel(leftPolicyModel, rightPolicyModel, useLeftOnMatches, false, failOnDuplicateKeys);
+ }
+
+ /**
+ * Get a merged policy model with information from two policy models merged into a larger policy
+ * model.
+ *
+ * @param leftPolicyModel the source Apex Model
+ * @param rightPolicyModel the policies to include in sub policy model
+ * @param useLeftOnMatches if true, uses concepts from the left model if concepts with common
+ * keys are found, if false it uses the concepts from the right model
+ * @param ignoreInvalidSource Ignore errors on the source model, do the best you can
+ * @param failOnDuplicateKeys whether to fail or not on the occurence of duplicate concept keys
+ * @return the new Destination Model
+ * @throws ApexModelException on model transfer errors
+ */
+ public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel,
+ final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches, final boolean ignoreInvalidSource,
+ final boolean failOnDuplicateKeys) throws ApexModelException {
+
+ if (!ignoreInvalidSource) {
+ validateModels(leftPolicyModel, "left");
+ validateModels(rightPolicyModel, "right");
+ }
+
+ // The new policy model uses the favoured copy side as its base
+ final AxPolicyModel mergedPolicyModel =
+ (useLeftOnMatches ? new AxPolicyModel(leftPolicyModel) : new AxPolicyModel(rightPolicyModel));
+
+ // The Compared to policy model is the unfavoured side
+ final AxPolicyModel copyFromPolicyModel =
+ (useLeftOnMatches ? new AxPolicyModel(rightPolicyModel) : new AxPolicyModel(leftPolicyModel));
+
+ Map<AxArtifactKey, AxKeyInfo> mergedKeyInfoMap = mergedPolicyModel.getKeyInformation().getKeyInfoMap();
+ Map<AxArtifactKey, AxContextSchema> mergedSchemasMap = mergedPolicyModel.getSchemas().getSchemasMap();
+ Map<AxArtifactKey, AxEvent> mergedEventMap = mergedPolicyModel.getEvents().getEventMap();
+ Map<AxArtifactKey, AxContextAlbum> mergedAlbumsMap = mergedPolicyModel.getAlbums().getAlbumsMap();
+ Map<AxArtifactKey, AxTask> mergedTaskMap = mergedPolicyModel.getTasks().getTaskMap();
+ Map<AxArtifactKey, AxPolicy> mergedPolicyMap = mergedPolicyModel.getPolicies().getPolicyMap();
+
+ Map<AxArtifactKey, AxKeyInfo> copyOverKeyInfoMap = copyFromPolicyModel.getKeyInformation().getKeyInfoMap();
+ Map<AxArtifactKey, AxContextSchema> copyOverSchemasMap = copyFromPolicyModel.getSchemas().getSchemasMap();
+ Map<AxArtifactKey, AxEvent> copyOverEventMap = copyFromPolicyModel.getEvents().getEventMap();
+ Map<AxArtifactKey, AxContextAlbum> copyOverAlbumsMap = copyFromPolicyModel.getAlbums().getAlbumsMap();
+ Map<AxArtifactKey, AxTask> copyOverTaskMap = copyFromPolicyModel.getTasks().getTaskMap();
+ Map<AxArtifactKey, AxPolicy> copyOverPolicyMap = copyFromPolicyModel.getPolicies().getPolicyMap();
+
+ if (failOnDuplicateKeys) {
+ StringBuilder errorMessage = new StringBuilder();
+ checkForDuplicateItem(mergedSchemasMap, copyOverSchemasMap, errorMessage, "schema");
+ checkForDuplicateItem(mergedEventMap, copyOverEventMap, errorMessage, "event");
+ checkForDuplicateItem(mergedAlbumsMap, copyOverAlbumsMap, errorMessage, "album");
+ checkForDuplicateItem(mergedTaskMap, copyOverTaskMap, errorMessage, "task");
+ checkForDuplicateItem(mergedPolicyMap, copyOverPolicyMap, errorMessage, "policy");
+ if (errorMessage.length() > 0) {
+ throw new ApexModelException(errorMessage.toString());
+ }
+ } else {
+ //  Remove entries that already exist
+ copyOverKeyInfoMap.keySet().removeIf(mergedKeyInfoMap::containsKey);
+ copyOverSchemasMap.keySet().removeIf(mergedSchemasMap::containsKey);
+ copyOverEventMap.keySet().removeIf(mergedEventMap::containsKey);
+ copyOverAlbumsMap.keySet().removeIf(mergedAlbumsMap::containsKey);
+ copyOverTaskMap.keySet().removeIf(mergedTaskMap::containsKey);
+ copyOverPolicyMap.keySet().removeIf(mergedPolicyMap::containsKey);
+ }
+ // Now add all the concepts that must be copied over
+ mergedKeyInfoMap.putAll(copyOverKeyInfoMap);
+ mergedSchemasMap.putAll(copyOverSchemasMap);
+ mergedEventMap.putAll(copyOverEventMap);
+ mergedAlbumsMap.putAll(copyOverAlbumsMap);
+ mergedTaskMap.putAll(copyOverTaskMap);
+ mergedPolicyMap.putAll(copyOverPolicyMap);
+
+ // That's it, return the model
+ return mergedPolicyModel;
+ }
+
+ /**
+ * Method to check for duplicate items.
+ *
+ * @param <V> the concept type
+ * @param mergedItemsMap the map to which items are copied
+ * @param copyOverItemsMap the map from where items are copied
+ * @param errorMessage error message in case of any duplicate concepts
+ * @param itemType the type of concept to specify distinguished error messages
+ */
+ public static <V> void checkForDuplicateItem(Map<AxArtifactKey, V> mergedItemsMap,
+ Map<AxArtifactKey, V> copyOverItemsMap, StringBuilder errorMessage, String itemType) {
+ for (Entry<AxArtifactKey, V> entry : copyOverItemsMap.entrySet()) {
+ V item = mergedItemsMap.get(entry.getKey());
+ // same item with different definitions cannot occur in multiple policies
+ if (null != item) {
+ if (item.equals(entry.getValue())) {
+ LOGGER.info("Same {} - {} is used by multiple policies.", itemType, entry.getKey().getId());
+ } else {
+ errorMessage.append("\n Same " + itemType + " - ").append(entry.getKey().getId())
+ .append(" with different definitions used in different policies");
+ }
+ }
+ }
+ }
+
+ private static void validateModels(AxPolicyModel policyModel, String position) throws ApexModelException {
+ // Validate the model
+ final AxValidationResult validationResult = new AxValidationResult();
+ policyModel.validate(validationResult);
+ if (!validationResult.isValid()) {
+ String message = position + " model is invalid: " + validationResult.toString();
+ LOGGER.warn(message);
+ throw new ApexModelException(message);
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitter.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitter.java
new file mode 100644
index 000000000..1f1c27a83
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitter.java
@@ -0,0 +1,165 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.TreeSet;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * Helper class used to extract information from a policy model into a policy model that is a subset of the original
+ * policy model.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class PolicyModelSplitter {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyModelSplitter.class);
+
+ /**
+ * Private constructor used to prevent sub class instantiation.
+ */
+ private PolicyModelSplitter() {
+ // Private constructor to block subclassing
+ }
+
+ /**
+ * Get a sub policy model with only the information required for the specified policies from a larger policy model.
+ *
+ * @param sourcePolicyModel the source Apex Model
+ * @param subPolicies the policies to include in sub policy model
+ * @return the new Destination Model
+ * @throws ApexModelException on model transfer errors
+ */
+ public static AxPolicyModel getSubPolicyModel(final AxPolicyModel sourcePolicyModel,
+ final Collection<AxArtifactKey> subPolicies) throws ApexModelException {
+ return getSubPolicyModel(sourcePolicyModel, subPolicies, false);
+ }
+
+ /**
+ * Get a sub policy model with only the information required for the specified policies from a larger policy model.
+ *
+ * @param sourcePolicyModel the source Apex Model
+ * @param subPolicies the policies to include in sub policy model
+ * @param ignoreInvalidSource Ignore errors on the source model, do the best you can
+ * @return the new Destination Model
+ * @throws ApexModelException on model transfer errors
+ */
+ public static AxPolicyModel getSubPolicyModel(final AxPolicyModel sourcePolicyModel,
+ final Collection<AxArtifactKey> subPolicies, final boolean ignoreInvalidSource) throws ApexModelException {
+ // Validate the source model
+ if (!ignoreInvalidSource) {
+ final AxValidationResult sourceValidationResult = new AxValidationResult();
+ sourcePolicyModel.validate(sourceValidationResult);
+ if (!sourceValidationResult.isValid()) {
+ String message = "source model is invalid: " + sourceValidationResult.toString();
+ LOGGER.warn(message);
+ throw new ApexModelException(message);
+ }
+ }
+
+ // The new policy model
+ final AxPolicyModel newPolicyModel = new AxPolicyModel(sourcePolicyModel.getKey());
+ newPolicyModel.getKeyInformation().setKey(sourcePolicyModel.getKeyInformation().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getKey()));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getKeyInformation().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap()
+ .get(sourcePolicyModel.getKeyInformation().getKey()));
+
+ //  Get the events, tasks, context maps, and data types used by each policy
+ final Set<AxArtifactKey> contextSchemaSet = new TreeSet<>();
+ final Set<AxArtifactKey> eventSet = new TreeSet<>();
+ final Set<AxArtifactKey> contextAlbumSet = new TreeSet<>();
+ final Set<AxArtifactKey> taskSet = new TreeSet<>();
+
+ newPolicyModel.getPolicies().setKey(sourcePolicyModel.getPolicies().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getPolicies().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getPolicies().getKey()));
+ for (final AxArtifactKey subPolicyKey : subPolicies) {
+ final AxPolicy subPolicy = sourcePolicyModel.getPolicies().getPolicyMap().get(subPolicyKey);
+ if (subPolicy == null) {
+ LOGGER.warn("source sub policy not found: {}", subPolicyKey);
+ continue;
+ }
+
+ // Transfer the policy across
+ newPolicyModel.getPolicies().getPolicyMap().put(subPolicyKey, subPolicy);
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(subPolicyKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(subPolicyKey));
+
+ // Get the references for this policy
+ final PolicyAnalysisResult analysisResult = new PolicyAnalyser().analyse(sourcePolicyModel, subPolicy);
+ contextSchemaSet.addAll(analysisResult.getUsedContextSchemas());
+ eventSet.addAll(analysisResult.getUsedEvents());
+ contextAlbumSet.addAll(analysisResult.getUsedContextAlbums());
+ taskSet.addAll(analysisResult.getUsedTasks());
+
+ }
+
+ // Now add all the referenced data types, events, context maps, and tasks to the policy
+ // model
+ newPolicyModel.getSchemas().setKey(sourcePolicyModel.getSchemas().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getSchemas().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getSchemas().getKey()));
+ for (final AxArtifactKey contextSchemaKey : contextSchemaSet) {
+ newPolicyModel.getSchemas().getSchemasMap().put(contextSchemaKey,
+ sourcePolicyModel.getSchemas().getSchemasMap().get(contextSchemaKey));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(contextSchemaKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(contextSchemaKey));
+ }
+ newPolicyModel.getEvents().setKey(sourcePolicyModel.getEvents().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getEvents().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getEvents().getKey()));
+ for (final AxArtifactKey eventKey : eventSet) {
+ newPolicyModel.getEvents().getEventMap().put(eventKey,
+ sourcePolicyModel.getEvents().getEventMap().get(eventKey));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(eventKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(eventKey));
+ }
+ newPolicyModel.getAlbums().setKey(sourcePolicyModel.getAlbums().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getAlbums().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getAlbums().getKey()));
+ for (final AxArtifactKey contextAlbumKey : contextAlbumSet) {
+ newPolicyModel.getAlbums().getAlbumsMap().put(contextAlbumKey,
+ sourcePolicyModel.getAlbums().getAlbumsMap().get(contextAlbumKey));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(contextAlbumKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(contextAlbumKey));
+ }
+ newPolicyModel.getTasks().setKey(sourcePolicyModel.getTasks().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getTasks().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getTasks().getKey()));
+ for (final AxArtifactKey taskKey : taskSet) {
+ newPolicyModel.getTasks().getTaskMap().put(taskKey, sourcePolicyModel.getTasks().getTaskMap().get(taskKey));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(taskKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(taskKey));
+ }
+
+ // That's it, return the model
+ return newPolicyModel;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/package-info.java b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/package-info.java
new file mode 100644
index 000000000..f84befd26
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/policymodel/handling/package-info.java
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Contains utility classes used to handle APEX polcies and policy models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.policymodel.handling;
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/CollectionUtils.java b/model/src/main/java/org/onap/policy/apex/model/utilities/CollectionUtils.java
new file mode 100644
index 000000000..9636ea7ce
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/CollectionUtils.java
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities;
+
+import java.util.List;
+import java.util.ListIterator;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+/**
+ * This is common utility class with static methods for handling collections.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class CollectionUtils {
+
+ /**
+ * Compare two lists, checks for equality, then for equality on members.
+ *
+ * @param <T> The type of the lists being compared
+ * @param leftList The leftmost List
+ * @param rightList The rightmost list
+ * @return an integer indicating how different the lists are
+ */
+ public static <T> int compareLists(final List<? extends Comparable<T>> leftList,
+ final List<? extends Comparable<T>> rightList) {
+ // Check for nulls
+ if (leftList == null && rightList == null) {
+ return 0;
+ }
+ if (leftList != null && rightList == null) {
+ return -1;
+ }
+ if (leftList == null) {
+ return 1;
+ }
+
+ // Check for equality
+ if (leftList.equals(rightList)) {
+ return 0;
+ }
+
+ return compareListEntries(leftList, rightList);
+ }
+
+ /**
+ * Compare two lists for equality on members.
+ *
+ * @param <T> The type of the lists being compared
+ * @param leftList The leftmost List
+ * @param rightList The rightmost list
+ * @return an integer indicating how different the lists are
+ */
+ private static <T> int compareListEntries(final List<? extends Comparable<T>> leftList,
+ final List<? extends Comparable<T>> rightList) {
+
+ // Iterate down the lists till we find a difference
+ final ListIterator<?> leftIterator = leftList.listIterator();
+ final ListIterator<?> rightIterator = rightList.listIterator();
+
+ while (true) {
+ // Check the iterators
+ if (!leftIterator.hasNext() && !rightIterator.hasNext()) {
+ return 0;
+ }
+ if (leftIterator.hasNext() && !rightIterator.hasNext()) {
+ return -1;
+ }
+ if (!leftIterator.hasNext() && rightIterator.hasNext()) {
+ return 1;
+ }
+
+ // Get the next objects
+ @SuppressWarnings("unchecked")
+ final var leftObject = (T) leftIterator.next();
+ @SuppressWarnings("unchecked")
+ final var rightObject = (T) rightIterator.next();
+
+ // Compare the objects
+ @SuppressWarnings("unchecked")
+ final int comparisonResult = ((Comparable<T>) leftObject).compareTo(rightObject);
+
+ // Check the comparison result
+ if (comparisonResult != 0) {
+ return comparisonResult;
+ }
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/DirectoryDeleteShutdownHook.java b/model/src/main/java/org/onap/policy/apex/model/utilities/DirectoryDeleteShutdownHook.java
new file mode 100644
index 000000000..21c417c4d
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/DirectoryDeleteShutdownHook.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class DirectoryShutdownHook removes the contents of a directory and the directory itself at shutdown.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+final class DirectoryDeleteShutdownHook extends Thread {
+
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(DirectoryUtils.class);
+
+ // The directory we are acting on
+ private final File tempDir;
+
+ /**
+ * Constructor that defines the directory to act on at shutdown.
+ *
+ * @param tempDir The temporary directory to delete
+ */
+ DirectoryDeleteShutdownHook(final File tempDir) {
+ this.tempDir = tempDir;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void run() {
+ if (tempDir.exists()) {
+ // Empty and delete the directory
+ DirectoryUtils.emptyDirectory(tempDir);
+ try {
+ Files.delete(tempDir.toPath());
+ } catch (IOException e) {
+ LOGGER.warn("Failed to delete directory {}", tempDir, e);
+ }
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/DirectoryUtils.java b/model/src/main/java/org/onap/policy/apex/model/utilities/DirectoryUtils.java
new file mode 100644
index 000000000..b0e8332b1
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/DirectoryUtils.java
@@ -0,0 +1,110 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This is common utility class with static methods for handling directories. It is an abstract class to prevent any
+ * direct instantiation and private constructor to prevent extending this class.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class DirectoryUtils {
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(DirectoryUtils.class);
+
+ /**
+ * Method to get an empty temporary directory in the system temporary directory on the local machine that will be
+ * deleted on (normal) shutdown.
+ *
+ * @param nameprefix The prefix of the filename. System.nanoTime() will be appended to the pattern to create a
+ * unique file pattern
+ * @return The temporary directory
+ */
+ public static File getLocalTempDirectory(final String nameprefix) {
+ try {
+ // Get the name of the temporary directory
+ final String tempDirName = System.getProperty("java.io.tmpdir") + "/" + nameprefix + System.nanoTime();
+ final var tempDir = new File(tempDirName);
+
+ // Delete the directory if it already exists
+ if (tempDir.exists()) {
+ return null;
+ }
+
+ // Make the directory
+ tempDir.mkdirs();
+
+ // Add a shutdown hook that deletes the directory contents when the JVM closes
+ Runtime.getRuntime().addShutdownHook(new DirectoryDeleteShutdownHook(tempDir));
+
+ LOGGER.trace("creating temp directory\"{}\" : ", tempDir.getAbsolutePath());
+ return tempDir;
+ } catch (final Exception e) {
+ LOGGER.debug("error creating temp directory\"{}\" : " + e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * Method to recursively delete all the files in a directory.
+ *
+ * @param tempDir the directory to empty
+ * @return true if the operation succeeds, false otherwise
+ */
+ public static boolean emptyDirectory(final File tempDir) {
+ // Sanity check
+ if (!tempDir.exists() || !tempDir.isDirectory()) {
+ return false;
+ }
+
+ // Walk the directory structure deleting files as we go
+ final File[] files = tempDir.listFiles();
+ if (files != null) {
+ for (final File directoryFile : files) {
+ // Check if this is a directory itself
+ if (directoryFile.isDirectory()) {
+ // Recurse into the sub directory and empty it
+ emptyDirectory(directoryFile);
+ }
+
+ // Delete the directory entry
+ try {
+ Files.delete(directoryFile.toPath());
+ } catch (IOException e) {
+ LOGGER.warn("Failed to delete directory file {}", directoryFile, e);
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/TreeMapUtils.java b/model/src/main/java/org/onap/policy/apex/model/utilities/TreeMapUtils.java
new file mode 100644
index 000000000..d8bb469cf
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/TreeMapUtils.java
@@ -0,0 +1,126 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+/**
+ * This class provides utility functions for tree maps. A function to find the nearest match in the tree map to an input
+ * string is provided.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class TreeMapUtils {
+
+ /**
+ * Find the list of entries that matches a given word, for example "p" will match "put", "policy", and "push".
+ *
+ * @param <T> the generic type for the value of the tree map
+ * @param searchMap the map that the method operates on
+ * @param word the word to search for
+ * @return the list of entries in the {@code searchMap} that match the {@code word}
+ */
+ public static <T> List<Entry<String, T>> findMatchingEntries(final NavigableMap<String, T> searchMap,
+ final String word) {
+ final List<Entry<String, T>> foundNodes = new ArrayList<>();
+
+ // A straight match check
+ if (searchMap.containsKey(word)) {
+ foundNodes.add(new SimpleEntry<>(word, searchMap.get(word)));
+ return foundNodes;
+ }
+
+ // Set up the beginning point for our search for a list of near matches
+ String foundKeyword = searchMap.floorKey(word);
+ if (foundKeyword == null) {
+ foundKeyword = searchMap.firstKey();
+ } else {
+ foundKeyword = searchMap.higherKey(foundKeyword);
+ }
+
+ // Find all the nodes that start with the word we are searching for
+ while (foundKeyword != null) {
+ if (foundKeyword.startsWith(word)) {
+ foundNodes.add(new SimpleEntry<>(foundKeyword, searchMap.get(foundKeyword)));
+ foundKeyword = searchMap.higherKey(foundKeyword);
+ } else {
+ break;
+ }
+ }
+ return foundNodes;
+ }
+
+ /**
+ * Compares two maps.
+ * @param <K> Key type
+ * @param <V> Value type
+ * @param leftMap left map
+ * @param rightMap right map
+ * @return an integer indicating how different the maps are
+ */
+ @SuppressWarnings("unchecked")
+ public static <K, V> int compareMaps(Map<? extends Comparable<K>, ? extends Comparable<V>> leftMap,
+ Map<? extends Comparable<K>, ? extends Comparable<V>> rightMap) {
+ if (leftMap == rightMap) {
+ return 0;
+ }
+
+ Iterator<?> leftIt = leftMap.entrySet().iterator();
+ Iterator<?> rightIt = rightMap.entrySet().iterator();
+
+ while (leftIt.hasNext() && rightIt.hasNext()) {
+ Map.Entry<?, ?> leftEntry = (Entry<?, ?>) leftIt.next();
+ Map.Entry<?, ?> rightEntry = (Entry<?, ?>) rightIt.next();
+
+ var leftKey = (K) leftEntry.getKey();
+ var rightKey = (K) rightEntry.getKey();
+ int result = ((Comparable<K>) leftKey).compareTo(rightKey);
+ if (result != 0) {
+ return result;
+ }
+
+ var leftValue = (V) leftEntry.getValue();
+ var rightValue = (V) rightEntry.getValue();
+ result = ((Comparable<V>) leftValue).compareTo(rightValue);
+ if (result != 0) {
+ return result;
+ }
+ }
+
+ if (leftIt.hasNext()) {
+ return 1;
+ } else if (rightIt.hasNext()) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyComparer.java b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyComparer.java
new file mode 100644
index 000000000..f4d628405
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyComparer.java
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities.comparison;
+
+/**
+ * This class compares two keys and returns their differences. It is used in bulk comparisons in models where maps of
+ * keys are being compared. The {@link KeyComparer} that is returned does the actual comparison
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <K> the type of key being compared
+ */
+public class KeyComparer<K> {
+
+ /**
+ * Compare two keys and return their differences.
+ *
+ * @param leftKey The left key of the comparison
+ * @param rightKey The right key of the comparison
+ * @return The difference between the keys
+ */
+ public KeyDifference<K> compareKeys(final K leftKey, final K rightKey) {
+ return new KeyDifference<>(leftKey, rightKey);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyDifference.java b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyDifference.java
new file mode 100644
index 000000000..a0395cf16
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyDifference.java
@@ -0,0 +1,86 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities.comparison;
+
+import lombok.Getter;
+
+/**
+ * This class is used to template key differences for bulk key comparisons in models. It performs a difference check
+ * between two keys.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <K> the generic type
+ */
+@Getter
+public class KeyDifference<K> {
+ // The keys being compared
+ private K leftKey;
+ private K rightKey;
+
+ /**
+ * Constructor used to set the keys being compared.
+ *
+ * @param leftKey the left key that is being compared
+ * @param rightKey the right key that is being compared
+ */
+ public KeyDifference(final K leftKey, final K rightKey) {
+ this.leftKey = leftKey;
+ this.rightKey = rightKey;
+ }
+
+ /**
+ * Checks if the left and right keys are equal.
+ *
+ * @return true, if checks if is equal
+ */
+ public boolean isEqual() {
+ return leftKey.equals(rightKey);
+ }
+
+ /**
+ * Gets a string representation of the difference between the keys.
+ *
+ * @param diffsOnly if set, then a blank string is returned if the keys are equal
+ * @return the difference between the keys as a string
+ */
+ public String asString(final boolean diffsOnly) {
+ var builder = new StringBuilder();
+
+ if (leftKey.equals(rightKey)) {
+ if (!diffsOnly) {
+ builder.append("left key ");
+ builder.append(leftKey);
+ builder.append(" equals right key ");
+ builder.append(rightKey);
+ builder.append('\n');
+ }
+ } else {
+ builder.append("left key ");
+ builder.append(leftKey);
+ builder.append(" and right key ");
+ builder.append(rightKey);
+ builder.append(" differ\n");
+ }
+
+ return builder.toString();
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapComparer.java b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapComparer.java
new file mode 100644
index 000000000..9943690fa
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapComparer.java
@@ -0,0 +1,96 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities.comparison;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Compare two maps and returns their differences. The types of the keys and the values in the two maps being comapred
+ * must be the same. The class returns entries that are only in the left map, only in the right map, entries that have
+ * identical keys and different values and entries that have different keys and different values in a
+ * {@link KeyedMapDifference} instance.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <K> the type of the keys in the maps being compared
+ * @param <V> the type of the values in the maps being compared
+ */
+public class KeyedMapComparer<K, V> {
+ /**
+ * Compare two maps and return their differences in a {@link KeyedMapDifference} instance.
+ *
+ * @param leftMap The left map to be compared
+ * @param rightMap The right map to be compared
+ * @return The common, left only, and right only maps in a {@link KeyedMapDifference} instance
+ */
+ public KeyedMapDifference<K, V> compareMaps(final Map<K, V> leftMap, final Map<K, V> rightMap) {
+ KeyedMapDifference<K, V> result = new KeyedMapDifference<>();
+
+ // Get the keys that are only in the left map
+ Set<K> leftOnlyKeys = new TreeSet<>(leftMap.keySet());
+ leftOnlyKeys.removeAll(rightMap.keySet());
+
+ // Get the keys that are only in the right map
+ Set<K> rightOnlyKeys = new TreeSet<>(rightMap.keySet());
+ rightOnlyKeys.removeAll(leftMap.keySet());
+
+ // Find the keys common across both maps
+ Set<K> commonKeys = new TreeSet<>(rightMap.keySet());
+ commonKeys.addAll(leftMap.keySet());
+ commonKeys.removeAll(leftOnlyKeys);
+ commonKeys.removeAll(rightOnlyKeys);
+
+ // Now save the left values
+ for (K key : leftOnlyKeys) {
+ result.getLeftOnly().put(key, leftMap.get(key));
+ }
+
+ // Now save the right values
+ for (K key : rightOnlyKeys) {
+ result.getRightOnly().put(key, rightMap.get(key));
+ }
+
+ // Save the common values to two maps, an identical and different map
+ for (K key : commonKeys) {
+ // Check if the values are identical in each map
+ var leftValue = leftMap.get(key);
+ var rightValue = rightMap.get(key);
+
+ // Store as appropriate
+ if (leftValue.equals(rightValue)) {
+ result.getIdenticalValues().put(key, leftValue);
+ } else {
+ // Store the two values
+ List<V> valueList = new ArrayList<>();
+ valueList.add(leftValue);
+ valueList.add(rightValue);
+
+ result.getDifferentValues().put(key, valueList);
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapDifference.java b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapDifference.java
new file mode 100644
index 000000000..e10854926
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapDifference.java
@@ -0,0 +1,174 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities.comparison;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import lombok.Getter;
+
+/**
+ * This class holds the result of a difference check between two keyed maps. Four results are returned in the class. The
+ * {@code leftOnly} result is the entries that appear only in the left map. the {@code rightOnly} result is the entries
+ * that appear only in the right map. The {@code differentValues} result are the entries that have the same key but
+ * different values in the maps being compared. The {@code identicalValues} result are the entries with identical keys
+ * and values in both maps being compared.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <K> the generic type
+ * @param <V> the generic type
+ */
+@Getter
+public class KeyedMapDifference<K, V> {
+ private static final String KEY = "key=";
+ private static final String VALUE = ",value=";
+
+ // Three maps to hold the comparison result
+ private Map<K, V> leftOnly = new TreeMap<>();
+ private Map<K, V> rightOnly = new TreeMap<>();
+ private Map<K, V> identicalValues = new TreeMap<>();
+ private Map<K, List<V>> differentValues = new TreeMap<>();
+
+ /**
+ * Return a string representation of the differences.
+ *
+ * @param diffsOnly if set, then a blank string is returned if the maps are equal
+ * @param keysOnly if set, then a terse string that prints only the keys is returned, otherwise both keys and values
+ * are printed
+ * @return the string
+ */
+ public String asString(final boolean diffsOnly, final boolean keysOnly) {
+ var builder = new StringBuilder();
+
+ if (leftOnly.isEmpty()) {
+ if (!diffsOnly) {
+ builder.append("*** all left keys in right\n");
+ }
+ } else {
+ builder.append(getInOneSideOnlyAsString(leftOnly, "left", keysOnly));
+ }
+
+ if (rightOnly.isEmpty()) {
+ if (!diffsOnly) {
+ builder.append("*** all right keys in left\n");
+ }
+ } else {
+ builder.append(getInOneSideOnlyAsString(rightOnly, "right", keysOnly));
+ }
+
+ if (differentValues.isEmpty()) {
+ if (!diffsOnly) {
+ builder.append("*** all values in left and right are identical\n");
+ }
+ } else {
+ builder.append(getDifferencesAsString(keysOnly));
+ }
+
+ if (!diffsOnly) {
+ builder.append(getIdenticalsAsString(keysOnly));
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Output the entries in a map with entries that are in one side only as a string.
+ *
+ * @param sideMap the map for the side being checked
+ * @param sideMapString the string that represents the map in output strings
+ * @param keysOnly if true, just add key information and not entries
+ * @return the entries as a string
+ */
+ private Object getInOneSideOnlyAsString(final Map<K, V> sideMap, final String sideMapString,
+ final boolean keysOnly) {
+ var builder = new StringBuilder();
+
+ builder.append("*** list of keys on " + sideMapString + " only\n");
+ for (Entry<K, V> leftEntry : sideMap.entrySet()) {
+ builder.append(KEY);
+ builder.append(leftEntry.getKey());
+ if (!keysOnly) {
+ builder.append(VALUE);
+ builder.append(leftEntry.getValue());
+ }
+ builder.append('\n');
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Output the differences between two the maps as a string.
+ *
+ * @param keysOnly if true, just add key information and not entries
+ * @return the differences as a string
+ */
+ private String getDifferencesAsString(final boolean keysOnly) {
+ var builder = new StringBuilder();
+
+ builder.append("*** list of differing entries between left and right\n");
+ for (Entry<K, List<V>> differentEntry : differentValues.entrySet()) {
+ builder.append(KEY);
+ builder.append(differentEntry.getKey());
+ if (!keysOnly) {
+ builder.append(",values={");
+ var first = true;
+ for (V differentEntryValue : differentEntry.getValue()) {
+ builder.append(differentEntryValue);
+ if (first) {
+ first = false;
+ } else {
+ builder.append(',');
+ }
+ }
+ builder.append("}");
+ }
+ builder.append('\n');
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Output the identical entries in the maps as a string.
+ *
+ * @param keysOnly if true, just add key information and not entries
+ * @return the identical entries as a string
+ */
+ private String getIdenticalsAsString(final boolean keysOnly) {
+ var builder = new StringBuilder();
+
+ builder.append("*** list of identical entries in left and right\n");
+ for (Entry<K, V> identicalEntry : identicalValues.entrySet()) {
+ builder.append(KEY);
+ builder.append(identicalEntry.getKey());
+ if (!keysOnly) {
+ builder.append(VALUE);
+ builder.append(identicalEntry.getValue());
+ }
+ builder.append('\n');
+ }
+
+ return builder.toString();
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/package-info.java b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/package-info.java
new file mode 100644
index 000000000..f0488eacd
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/comparison/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Provides utility template classes that compare keys and maps of any type.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.utilities.comparison;
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/json/JsonHandler.java b/model/src/main/java/org/onap/policy/apex/model/utilities/json/JsonHandler.java
new file mode 100644
index 000000000..66e389fa2
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/json/JsonHandler.java
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities.json;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+/**
+ * This class reads objects of the given class from an input stream.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @param <P> the generic type
+ */
+public class JsonHandler<P> {
+ private static final Gson GSON = new GsonBuilder().serializeNulls().create();
+
+ /**
+ * This method reads objects of a given class from an input stream.
+ *
+ * @param inputClass The class to read
+ * @param inputStream the input stream to read from
+ * @return the object read
+ */
+ public P read(final Class<P> inputClass, final InputStream inputStream) {
+ final Reader jsonResourceReader = new InputStreamReader(inputStream);
+ return GSON.fromJson(jsonResourceReader, inputClass);
+ }
+}
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/json/package-info.java b/model/src/main/java/org/onap/policy/apex/model/utilities/json/package-info.java
new file mode 100755
index 000000000..f9d1304d7
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/json/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Provides a utility class for reading JSON streams.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.utilities.json;
diff --git a/model/src/main/java/org/onap/policy/apex/model/utilities/package-info.java b/model/src/main/java/org/onap/policy/apex/model/utilities/package-info.java
new file mode 100644
index 000000000..446d009ba
--- /dev/null
+++ b/model/src/main/java/org/onap/policy/apex/model/utilities/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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=========================================================
+ */
+
+/**
+ * Provides utility classes that are used in APEX models and indeed in other packages that use APEX models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.utilities;
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetterImplTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetterImplTest.java
new file mode 100644
index 000000000..44a9de49e
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxConceptGetterImplTest.java
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.basicmodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.NavigableMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.junit.Test;
+
+/**
+ * Test the AxConceptGetterImpl class.
+ */
+public class AxConceptGetterImplTest {
+
+ @Test
+ public void testAxConceptGetterImpl() {
+ NavigableMap<AxArtifactKey, AxArtifactKey> keyMap = new TreeMap<>();
+
+ AxConceptGetterImpl<AxArtifactKey> getter = new AxConceptGetterImpl<>(keyMap);
+ assertNotNull(getter);
+
+ AxArtifactKey keyA = new AxArtifactKey("A", "0.0.1");
+ assertNull(getter.get(keyA));
+
+ assertThatThrownBy(() -> getter.get((String) null))
+ .hasMessage("conceptKeyName may not be null");
+ assertNull(getter.get("W"));
+
+ AxArtifactKey keyZ = new AxArtifactKey("Z", "0.0.1");
+ keyMap.put(keyZ, keyZ);
+ assertNull(getter.get("W"));
+
+ AxArtifactKey keyW001 = new AxArtifactKey("W", "0.0.1");
+ keyMap.put(keyW001, keyW001);
+ assertEquals(keyW001, getter.get("W"));
+
+ AxArtifactKey keyW002 = new AxArtifactKey("W", "0.0.2");
+ keyMap.put(keyW002, keyW002);
+ assertEquals(keyW002, getter.get("W"));
+
+ keyMap.remove(keyZ);
+ assertEquals(keyW002, getter.get("W"));
+
+ assertThatThrownBy(() -> getter.get((String) null, "0.0.1"))
+ .hasMessage("conceptKeyName may not be null");
+ assertEquals(keyW002, getter.get("W", "0.0.2"));
+ assertEquals(keyW002, getter.get("W", (String) null));
+
+ assertEquals(new TreeSet<AxArtifactKey>(keyMap.values()), getter.getAll(null));
+ assertEquals(new TreeSet<AxArtifactKey>(keyMap.values()), getter.getAll(null, null));
+
+ assertEquals(keyW001, getter.getAll("W", null).iterator().next());
+ assertEquals(keyW002, getter.getAll("W", "0.0.2").iterator().next());
+ assertEquals(0, getter.getAll("A", null).size());
+ assertEquals(0, getter.getAll("Z", null).size());
+
+ keyMap.put(keyZ, keyZ);
+ assertEquals(keyW002, getter.getAll("W", "0.0.2").iterator().next());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfoTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfoTest.java
new file mode 100644
index 000000000..0c7edee28
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfoTest.java
@@ -0,0 +1,108 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-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.onap.policy.apex.model.basicmodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.UUID;
+import org.junit.Test;
+
+
+public class AxKeyInfoTest {
+
+ @Test
+ public void testNullAxKeyInfo() {
+ assertNotNull(new AxKeyInfo());
+ assertNotNull(new AxKeyInfo(new AxArtifactKey()));
+ assertNotNull(new AxKeyInfo(new AxArtifactKey(), UUID.randomUUID(), "Key description"));
+ }
+
+ @Test
+ public void testAxKeyInfo() {
+ AxKeyInfo testKeyInfo = new AxKeyInfo();
+ testKeyInfo.setKey((new AxArtifactKey("PN", "0.0.1")));
+ assertEquals("PN:0.0.1", testKeyInfo.getKey().getId());
+ assertTrue(testKeyInfo.matchesId("PN:0.0.1"));
+
+ AxArtifactKey key = new AxArtifactKey("key", "0.0.1");
+ testKeyInfo.setKey(key);
+ assertEquals(key, testKeyInfo.getKey());
+
+ UUID uuid = UUID.randomUUID();
+ testKeyInfo.setUuid(uuid);
+ assertEquals(uuid, testKeyInfo.getUuid());
+ testKeyInfo.setDescription("Key Description");
+ assertEquals("Key Description", testKeyInfo.getDescription());
+
+ AxKeyInfo clonedReferenceKey = new AxKeyInfo(testKeyInfo);
+ assertTrue(clonedReferenceKey.toString()
+ .startsWith("AxKeyInfo:(artifactId=AxArtifactKey:(name=key,version=0.0.1),uuid="));
+
+ assertNotEquals(0, testKeyInfo.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(testKeyInfo, testKeyInfo); // NOSONAR
+ assertEquals(testKeyInfo, clonedReferenceKey);
+ assertNotNull(testKeyInfo);
+ Object differentKeyType = new AxArtifactKey();
+ assertNotEquals(testKeyInfo, differentKeyType);
+ assertNotEquals(testKeyInfo, new AxKeyInfo(new AxArtifactKey()));
+ assertNotEquals(testKeyInfo, new AxKeyInfo(key, UUID.randomUUID(), "Some Description"));
+ assertEquals(testKeyInfo, new AxKeyInfo(key, uuid, "Some Other Description"));
+ assertEquals(testKeyInfo, new AxKeyInfo(key, uuid, "Key Description"));
+
+ assertEquals(0, testKeyInfo.compareTo(testKeyInfo));
+ assertEquals(0, testKeyInfo.compareTo(clonedReferenceKey));
+
+
+ }
+
+ @Test
+ public void testAxKeyValidation() {
+ AxKeyInfo testKeyInfo = new AxKeyInfo();
+ testKeyInfo.setKey((new AxArtifactKey("PN", "0.0.1")));
+
+ AxValidationResult result = new AxValidationResult();
+ result = testKeyInfo.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ testKeyInfo.setDescription("");
+ result = testKeyInfo.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.OBSERVATION, result.getValidationResult());
+
+ testKeyInfo.setUuid(new UUID(0, 0));
+ result = testKeyInfo.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.WARNING, result.getValidationResult());
+
+ testKeyInfo.setKey(AxArtifactKey.getNullKey());
+ result = testKeyInfo.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.INVALID, result.getValidationResult());
+
+ assertNotNull(AxKeyInfo.generateReproducibleUuid(null));
+ assertNotNull(AxKeyInfo.generateReproducibleUuid("SeedString"));
+
+ testKeyInfo.clean();
+ assertNotNull(testKeyInfo);
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyTest.java
new file mode 100644
index 000000000..010f4b8a3
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyTest.java
@@ -0,0 +1,189 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2021 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.onap.policy.apex.model.basicmodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey.Compatibility;
+
+public class AxKeyTest {
+
+ private static AxArtifactKey someKey0;
+ private static AxArtifactKey someKey1;
+ private static AxArtifactKey someKey2;
+ private static AxArtifactKey someKey3;
+ private static AxArtifactKey someKey4;
+ private static AxArtifactKey someKey5;
+ private static AxArtifactKey someKey6;
+
+ /**
+ * Sets data in Keys for the tests.
+ */
+ @Before
+ public void setKeys() {
+ someKey0 = new AxArtifactKey();
+ someKey1 = new AxArtifactKey("name", "0.0.1");
+ someKey2 = new AxArtifactKey(someKey1);
+ someKey3 = new AxArtifactKey(someKey1.getId());
+ someKey4 = new AxArtifactKey(someKey1);
+ someKey5 = new AxArtifactKey(someKey1);
+ someKey6 = new AxArtifactKey(someKey1);
+ }
+
+ private void setKeyValues() {
+ someKey0.setName("zero");
+ someKey0.setVersion("0.0.2");
+ someKey3.setVersion("0.0.2");
+ someKey4.setVersion("0.1.2");
+ someKey5.setVersion("1.2.2");
+ someKey6.setVersion("3");
+ }
+
+ @Test
+ public void testArtifactKey() {
+ assertThatThrownBy(() -> new AxArtifactKey("some bad key id"))
+ .hasMessage("parameter \"id\": value \"some bad key id\", "
+ + "does not match regular expression \"[A-Za-z0-9\\-_\\.]+:[0-9].[0-9].[0-9]\"");
+
+ assertEquals(AxArtifactKey.getNullKey(), someKey0);
+
+ assertEquals(someKey1, someKey2);
+ assertEquals(someKey1, someKey3);
+
+ assertEquals(someKey2, someKey1.getKey());
+ assertEquals(1, someKey1.getKeys().size());
+
+ setKeyValues();
+
+ someKey0.clean();
+ assertNotNull(someKey0.toString());
+
+ AxArtifactKey someKey7 = new AxArtifactKey(someKey1);
+ assertEquals(150332875, someKey7.hashCode());
+ assertEquals(0, someKey7.compareTo(someKey1));
+ assertEquals(-12, someKey7.compareTo(someKey0));
+
+ assertThatThrownBy(() -> someKey0.compareTo(null))
+ .hasMessage("comparison object may not be null");
+ assertEquals(0, someKey0.compareTo(someKey0));
+ assertEquals(353602977, someKey0.compareTo(new AxReferenceKey()));
+
+ assertNotNull(someKey0);
+ // disabling sonar because this code tests the equals() method
+ assertEquals(someKey0, someKey0); // NOSONAR
+ assertNotEquals(someKey0, (Object) new AxReferenceKey());
+ }
+
+ @Test
+ public void testAxCompatibility() {
+ setKeyValues();
+
+ assertEquals(Compatibility.DIFFERENT, someKey0.getCompatibility(new AxReferenceKey()));
+ assertEquals(Compatibility.DIFFERENT, someKey0.getCompatibility(someKey1));
+ assertEquals(Compatibility.IDENTICAL, someKey2.getCompatibility(someKey1));
+ assertEquals(Compatibility.PATCH, someKey3.getCompatibility(someKey1));
+ assertEquals(Compatibility.MINOR, someKey4.getCompatibility(someKey1));
+ assertEquals(Compatibility.MAJOR, someKey5.getCompatibility(someKey1));
+ assertEquals(Compatibility.MAJOR, someKey6.getCompatibility(someKey1));
+
+ assertTrue(someKey1.isCompatible(someKey2));
+ assertTrue(someKey1.isCompatible(someKey3));
+ assertTrue(someKey1.isCompatible(someKey4));
+ assertFalse(someKey1.isCompatible(someKey0));
+ assertFalse(someKey1.isCompatible(someKey5));
+ assertFalse(someKey1.isCompatible(new AxReferenceKey()));
+ }
+
+ @Test
+ public void testAxValidation() {
+ setKeyValues();
+
+ assertEquals(AxValidationResult.ValidationResult.VALID,
+ someKey0.validate(new AxValidationResult()).getValidationResult());
+ assertEquals(AxValidationResult.ValidationResult.VALID,
+ someKey1.validate(new AxValidationResult()).getValidationResult());
+ assertEquals(AxValidationResult.ValidationResult.VALID,
+ someKey2.validate(new AxValidationResult()).getValidationResult());
+ assertEquals(AxValidationResult.ValidationResult.VALID,
+ someKey3.validate(new AxValidationResult()).getValidationResult());
+ assertEquals(AxValidationResult.ValidationResult.VALID,
+ someKey4.validate(new AxValidationResult()).getValidationResult());
+ assertEquals(AxValidationResult.ValidationResult.VALID,
+ someKey5.validate(new AxValidationResult()).getValidationResult());
+ assertEquals(AxValidationResult.ValidationResult.VALID,
+ someKey6.validate(new AxValidationResult()).getValidationResult());
+ }
+
+ @Test
+ public void testNullKey() {
+ setKeyValues();
+
+ AxArtifactKey nullKey0 = AxArtifactKey.getNullKey();
+ assertTrue(nullKey0.isNullKey());
+ AxArtifactKey nullKey1 = new AxArtifactKey();
+ assertTrue(nullKey1.isNullKey());
+ AxArtifactKey nullKey2 = new AxArtifactKey(AxKey.NULL_KEY_NAME, AxKey.NULL_KEY_VERSION);
+ assertTrue(nullKey2.isNullKey());
+ AxArtifactKey notnullKey = new AxArtifactKey("Blah", AxKey.NULL_KEY_VERSION);
+ assertFalse(notnullKey.isNullKey());
+ }
+
+
+ @Test
+ public void testValidation() throws IllegalArgumentException, IllegalAccessException,
+ NoSuchFieldException, SecurityException {
+ AxArtifactKey testKey = new AxArtifactKey("TheKey", "0.0.1");
+ assertEquals("TheKey:0.0.1", testKey.getId());
+
+ Field nameField = testKey.getClass().getDeclaredField("name");
+ nameField.setAccessible(true);
+ nameField.set(testKey, "Key Name");
+ AxValidationResult validationResult = new AxValidationResult();
+ testKey.validate(validationResult);
+ nameField.set(testKey, "TheKey");
+ nameField.setAccessible(false);
+ assertEquals(
+ "name invalid-parameter name with value Key Name "
+ + "does not match regular expression [A-Za-z0-9\\-_\\.]+",
+ validationResult.getMessageList().get(0).getMessage());
+
+ Field versionField = testKey.getClass().getDeclaredField("version");
+ versionField.setAccessible(true);
+ versionField.set(testKey, "Key Version");
+ AxValidationResult validationResultV = new AxValidationResult();
+ testKey.validate(validationResultV);
+ versionField.set(testKey, "0.0.1");
+ versionField.setAccessible(false);
+ assertEquals(
+ "version invalid-parameter version with value Key Version "
+ + "does not match regular expression [A-Za-z0-9.]+",
+ validationResultV.getMessageList().get(0).getMessage());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyUseTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyUseTest.java
new file mode 100644
index 000000000..5346b6b21
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyUseTest.java
@@ -0,0 +1,78 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 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.onap.policy.apex.model.basicmodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey.Compatibility;
+
+public class AxKeyUseTest {
+
+ @Test
+ public void test() {
+ assertNotNull(new AxKeyUse());
+ assertNotNull(new AxKeyUse(new AxArtifactKey()));
+ assertNotNull(new AxKeyUse(new AxReferenceKey()));
+
+ AxArtifactKey key = new AxArtifactKey("Key", "0.0.1");
+ AxKeyUse keyUse = new AxKeyUse();
+ keyUse.setKey(key);
+ assertEquals(key, keyUse.getKey());
+ assertEquals("Key:0.0.1", keyUse.getId());
+ assertEquals(key, keyUse.getKeys().get(0));
+
+ assertEquals(Compatibility.IDENTICAL, keyUse.getCompatibility(key));
+ assertTrue(keyUse.isCompatible(key));
+
+ keyUse.clean();
+ assertNotNull(keyUse);
+
+ AxValidationResult result = new AxValidationResult();
+ result = keyUse.validate(result);
+ assertNotNull(result);
+
+ assertNotEquals(0, keyUse.hashCode());
+
+ AxKeyUse clonedKeyUse = new AxKeyUse(keyUse);
+ assertEquals("AxKeyUse:(usedKey=AxArtifactKey:(name=Key,version=0.0.1))", clonedKeyUse.toString());
+
+ assertNotEquals(0, keyUse.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(keyUse, keyUse); // NOSONAR
+ assertEquals(keyUse, clonedKeyUse);
+ assertNotEquals(keyUse, (Object) "Hello");
+ assertEquals(keyUse, new AxKeyUse(key));
+
+ assertEquals(0, keyUse.compareTo(keyUse));
+ assertEquals(0, keyUse.compareTo(clonedKeyUse));
+ assertNotEquals(0, keyUse.compareTo(new AxArtifactKey()));
+ assertEquals(0, keyUse.compareTo(new AxKeyUse(key)));
+
+ AxKeyUse keyUseNull = new AxKeyUse(AxArtifactKey.getNullKey());
+ AxValidationResult resultNull = new AxValidationResult();
+ assertEquals(false, keyUseNull.validate(resultNull).isValid());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxReferenceKeyTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxReferenceKeyTest.java
new file mode 100644
index 000000000..515587558
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/AxReferenceKeyTest.java
@@ -0,0 +1,177 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 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.onap.policy.apex.model.basicmodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import org.junit.Test;
+
+
+public class AxReferenceKeyTest {
+
+ @Test
+ public void testAxReferenceKey() {
+ assertNotNull(new AxReferenceKey());
+ assertNotNull(new AxReferenceKey(new AxArtifactKey()));
+ assertNotNull(new AxReferenceKey(new AxArtifactKey(), "LocalName"));
+ assertNotNull(new AxReferenceKey(new AxReferenceKey()));
+ assertNotNull(new AxReferenceKey(new AxReferenceKey(), "LocalName"));
+ assertNotNull(new AxReferenceKey(new AxArtifactKey(), "ParentLocalName", "LocalName"));
+ assertNotNull(new AxReferenceKey("ParentKeyName", "0.0.1", "LocalName"));
+ assertNotNull(new AxReferenceKey("ParentKeyName", "0.0.1", "ParentLocalName", "LocalName"));
+ assertNotNull(new AxReferenceKey("ParentKeyName:0.0.1:ParentLocalName:LocalName"));
+ assertEquals(AxReferenceKey.getNullKey().getKey(), AxReferenceKey.getNullKey());
+ assertEquals("NULL:0.0.0:NULL:NULL", AxReferenceKey.getNullKey().getId());
+
+ AxReferenceKey testReferenceKey = new AxReferenceKey();
+ testReferenceKey.setParentArtifactKey(new AxArtifactKey("PN", "0.0.1"));
+ assertEquals("PN:0.0.1", testReferenceKey.getParentArtifactKey().getId());
+
+ testReferenceKey.setParentReferenceKey(new AxReferenceKey("PN", "0.0.1", "LN"));
+ assertEquals("PN:0.0.1:NULL:LN", testReferenceKey.getParentReferenceKey().getId());
+
+ testReferenceKey.setParentKeyName("NPKN");
+ assertEquals("NPKN", testReferenceKey.getParentKeyName());
+
+ testReferenceKey.setParentKeyVersion("0.0.1");
+ assertEquals("0.0.1", testReferenceKey.getParentKeyVersion());
+
+ testReferenceKey.setParentLocalName("NPKLN");
+ assertEquals("NPKLN", testReferenceKey.getParentLocalName());
+
+ testReferenceKey.setLocalName("NLN");
+ assertEquals("NLN", testReferenceKey.getLocalName());
+
+ assertFalse(testReferenceKey.isCompatible(AxArtifactKey.getNullKey()));
+ assertFalse(testReferenceKey.isCompatible(AxReferenceKey.getNullKey()));
+ assertTrue(testReferenceKey.isCompatible(testReferenceKey));
+
+ assertEquals(AxKey.Compatibility.DIFFERENT, testReferenceKey.getCompatibility(AxArtifactKey.getNullKey()));
+ assertEquals(AxKey.Compatibility.DIFFERENT, testReferenceKey.getCompatibility(AxReferenceKey.getNullKey()));
+ assertEquals(AxKey.Compatibility.IDENTICAL, testReferenceKey.getCompatibility(testReferenceKey));
+
+ AxValidationResult result = new AxValidationResult();
+ result = testReferenceKey.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ testReferenceKey.clean();
+
+ AxReferenceKey clonedReferenceKey = new AxReferenceKey(testReferenceKey);
+ assertEquals("AxReferenceKey:(parentKeyName=NPKN,parentKeyVersion=0.0.1,parentLocalName=NPKLN,localName=NLN)",
+ clonedReferenceKey.toString());
+
+ assertNotEquals(0, testReferenceKey.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(testReferenceKey, testReferenceKey); // NOSONAR
+ assertEquals(testReferenceKey, clonedReferenceKey);
+ assertNotEquals(testReferenceKey, (Object) "Hello");
+ assertNotEquals(testReferenceKey, new AxReferenceKey("PKN", "0.0.2", "PLN", "LN"));
+ assertNotEquals(testReferenceKey, new AxReferenceKey("NPKN", "0.0.2", "PLN", "LN"));
+ assertNotEquals(testReferenceKey, new AxReferenceKey("NPKN", "0.0.1", "PLN", "LN"));
+ assertNotEquals(testReferenceKey, new AxReferenceKey("NPKN", "0.0.1", "NPLN", "LN"));
+ assertEquals(testReferenceKey, new AxReferenceKey("NPKN", "0.0.1", "NPKLN", "NLN"));
+
+ assertEquals(0, testReferenceKey.compareTo(testReferenceKey));
+ assertEquals(0, testReferenceKey.compareTo(clonedReferenceKey));
+ assertNotEquals(0, testReferenceKey.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, testReferenceKey.compareTo(new AxReferenceKey("PKN", "0.0.2", "PLN", "LN")));
+ assertNotEquals(0, testReferenceKey.compareTo(new AxReferenceKey("NPKN", "0.0.2", "PLN", "LN")));
+ assertNotEquals(0, testReferenceKey.compareTo(new AxReferenceKey("NPKN", "0.0.1", "PLN", "LN")));
+ assertNotEquals(0, testReferenceKey.compareTo(new AxReferenceKey("NPKN", "0.0.1", "NPLN", "LN")));
+ assertEquals(0, testReferenceKey.compareTo(new AxReferenceKey("NPKN", "0.0.1", "NPKLN", "NLN")));
+
+ assertNotNull(testReferenceKey.getKeys());
+
+ assertThatThrownBy(() -> testReferenceKey.equals(null))
+ .hasMessage("comparison object may not be null");
+ assertThatThrownBy(() -> testReferenceKey.copyTo(null))
+ .hasMessage("target may not be null");
+ assertThatThrownBy(() -> testReferenceKey.copyTo(new AxArtifactKey("Key", "0.0.1")))
+ .hasMessage("org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey is not an instance of "
+ + "org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey");
+ AxReferenceKey targetRefKey = new AxReferenceKey();
+ assertEquals(testReferenceKey, testReferenceKey.copyTo(targetRefKey));
+ }
+
+ @Test
+ public void testValidation() throws IllegalArgumentException, IllegalAccessException,
+ NoSuchFieldException, SecurityException {
+ AxReferenceKey testReferenceKey = new AxReferenceKey();
+ testReferenceKey.setParentArtifactKey(new AxArtifactKey("PN", "0.0.1"));
+ assertEquals("PN:0.0.1", testReferenceKey.getParentArtifactKey().getId());
+
+ Field parentNameField = testReferenceKey.getClass().getDeclaredField("parentKeyName");
+ parentNameField.setAccessible(true);
+ parentNameField.set(testReferenceKey, "Parent Name");
+ AxValidationResult validationResult = new AxValidationResult();
+ testReferenceKey.validate(validationResult);
+ parentNameField.set(testReferenceKey, "ParentName");
+ parentNameField.setAccessible(false);
+ assertEquals(
+ "parentKeyName invalid-parameter parentKeyName with value Parent Name "
+ + "does not match regular expression [A-Za-z0-9\\-_\\.]+",
+ validationResult.getMessageList().get(0).getMessage());
+
+ Field parentVersionField = testReferenceKey.getClass().getDeclaredField("parentKeyVersion");
+ parentVersionField.setAccessible(true);
+ parentVersionField.set(testReferenceKey, "Parent Version");
+ AxValidationResult validationResultPV = new AxValidationResult();
+ testReferenceKey.validate(validationResultPV);
+ parentVersionField.set(testReferenceKey, "0.0.1");
+ parentVersionField.setAccessible(false);
+ assertEquals(
+ "parentKeyVersion invalid-parameter parentKeyVersion with value Parent Version "
+ + "does not match regular expression [A-Za-z0-9.]+",
+ validationResultPV.getMessageList().get(0).getMessage());
+
+ Field parentLocalNameField = testReferenceKey.getClass().getDeclaredField("parentLocalName");
+ parentLocalNameField.setAccessible(true);
+ parentLocalNameField.set(testReferenceKey, "Parent Local Name");
+ AxValidationResult validationResultPL = new AxValidationResult();
+ testReferenceKey.validate(validationResultPL);
+ parentLocalNameField.set(testReferenceKey, "ParentLocalName");
+ parentLocalNameField.setAccessible(false);
+ assertEquals(
+ "parentLocalName invalid-parameter parentLocalName with value "
+ + "Parent Local Name does not match regular expression [A-Za-z0-9\\-_\\.]+|^$",
+ validationResultPL.getMessageList().get(0).getMessage());
+
+ Field localNameField = testReferenceKey.getClass().getDeclaredField("localName");
+ localNameField.setAccessible(true);
+ localNameField.set(testReferenceKey, "Local Name");
+ AxValidationResult validationResultLN = new AxValidationResult();
+ testReferenceKey.validate(validationResultLN);
+ localNameField.set(testReferenceKey, "LocalName");
+ localNameField.setAccessible(false);
+ assertEquals(
+ "localName invalid-parameter localName with value Local Name "
+ + "does not match regular expression [A-Za-z0-9\\-_\\.]+|^$",
+ validationResultLN.getMessageList().get(0).getMessage());
+
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/DummyEntity.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/DummyEntity.java
new file mode 100644
index 000000000..2b16e89ed
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/DummyEntity.java
@@ -0,0 +1,164 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.basicmodel.concepts;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class DummyEntity extends AxConcept {
+ private static final long serialVersionUID = -2962570563281067894L;
+
+ protected AxReferenceKey key;
+ private double doubleValue;
+
+ public DummyEntity() {
+ this.key = new AxReferenceKey();
+ this.doubleValue = 0;
+ }
+
+ public DummyEntity(Double doubleValue) {
+ this.key = new AxReferenceKey();
+ this.doubleValue = doubleValue;
+ }
+
+ public DummyEntity(AxReferenceKey key, Double doubleValue) {
+ this.key = key;
+ this.doubleValue = doubleValue;
+ }
+
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ @Override
+ public List<AxKey> getKeys() {
+ return Arrays.asList((AxKey) getKey());
+ }
+
+ public void setKey(AxReferenceKey key) {
+ this.key = key;
+ }
+
+ public boolean checkSetKey() {
+ return (this.key != null);
+ }
+
+ public double getDoubleValue() {
+ return doubleValue;
+ }
+
+ public void setDoubleValue(double doubleValue) {
+ this.doubleValue = doubleValue;
+ }
+
+ @Override
+ public AxValidationResult validate(AxValidationResult result) {
+ return key.validate(result);
+ }
+
+ @Override
+ public void clean() {
+ key.clean();
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("doubleValue=");
+ builder.append(doubleValue);
+ return builder.toString();
+ }
+
+ @Override
+ public AxConcept copyTo(AxConcept target) {
+ final Object copyObject = ((target == null) ? new DummyEntity() : target);
+ if (copyObject instanceof DummyEntity) {
+ final DummyEntity copy = ((DummyEntity) copyObject);
+ if (this.checkSetKey()) {
+ copy.setKey(new AxReferenceKey(key));
+ } else {
+ copy.key = null;
+ }
+ copy.doubleValue = doubleValue;
+ return copy;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((key == null) ? 0 : key.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ DummyEntity other = (DummyEntity) obj;
+ if (key == null) {
+ if (other.key != null) {
+ return false;
+ }
+ } else if (!key.equals(other.key)) {
+ return false;
+ }
+ if (doubleValue != other.doubleValue) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int compareTo(AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ DummyEntity other = (DummyEntity) otherObj;
+ if (key == null) {
+ if (other.key != null) {
+ return 1;
+ }
+ } else if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (doubleValue != other.doubleValue) {
+ return Double.valueOf(doubleValue).compareTo(other.doubleValue);
+ }
+
+ return 0;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/ExceptionsTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/ExceptionsTest.java
new file mode 100644
index 000000000..ff87bc2d0
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/ExceptionsTest.java
@@ -0,0 +1,66 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import org.junit.Test;
+
+
+public class ExceptionsTest {
+
+ @Test
+ public void test() {
+ assertNotNull(new ApexException("Message"));
+ assertNotNull(new ApexException("Message", new AxArtifactKey()));
+ assertNotNull(new ApexException("Message", new IOException()));
+ assertNotNull(new ApexException("Message", new IOException(), new AxArtifactKey()));
+
+ AxArtifactKey key = new AxArtifactKey();
+ ApexException ae = new ApexException("Message", new IOException("IO exception message"), key);
+ assertEquals("Message\ncaused by: Message\ncaused by: IO exception message", ae.getCascadedMessage());
+ assertEquals(key, ae.getObject());
+
+ assertNotNull(new ApexRuntimeException("Message"));
+ assertNotNull(new ApexRuntimeException("Message", new AxArtifactKey()));
+ assertNotNull(new ApexRuntimeException("Message", new IOException()));
+ assertNotNull(new ApexRuntimeException("Message", new IOException(), new AxArtifactKey()));
+
+ AxArtifactKey rkey = new AxArtifactKey();
+ ApexRuntimeException re = new ApexRuntimeException("Runtime Message",
+ new IOException("IO runtime exception message"), rkey);
+ assertEquals("Runtime Message\ncaused by: Runtime Message\ncaused by: IO runtime exception message",
+ re.getCascadedMessage());
+ assertEquals(key, re.getObject());
+
+ assertNotNull(new ApexConceptException("Message"));
+ assertNotNull(new ApexConceptException("Message", new IOException()));
+
+ AxArtifactKey ckey = new AxArtifactKey();
+ ApexException ace = new ApexException("Concept Message", new IOException("IO concept exception message"), ckey);
+ assertEquals("Concept Message\ncaused by: Concept Message\ncaused by: IO concept exception message",
+ ace.getCascadedMessage());
+ assertEquals(ckey, ace.getObject());
+ }
+
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/ValidationTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/ValidationTest.java
new file mode 100644
index 000000000..21ae9b65c
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/concepts/ValidationTest.java
@@ -0,0 +1,90 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+public class ValidationTest {
+
+ @Test
+ public void test() {
+ AxValidationResult result = new AxValidationResult();
+ AxReferenceKey refKey = new AxReferenceKey("PK", "0.0.1", "PLN", "LN");
+ result = refKey.validate(result);
+
+ assertNotNull(result);
+ assertTrue(result.isOk());
+ assertTrue(result.isValid());
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+ assertNotNull(result.getMessageList());
+
+ AxValidationMessage vmess0 = new AxValidationMessage(AxArtifactKey.getNullKey(), AxArtifactKey.class,
+ ValidationResult.VALID, "Some message");
+ result.addValidationMessage(vmess0);
+
+ assertTrue(result.isOk());
+ assertTrue(result.isValid());
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+ assertNotNull(result.getMessageList());
+ assertNotNull("hello", result.toString());
+
+ AxValidationMessage vmess1 = new AxValidationMessage(AxArtifactKey.getNullKey(), AxArtifactKey.class,
+ ValidationResult.OBSERVATION, "Some message");
+ result.addValidationMessage(vmess1);
+
+ assertTrue(result.isOk());
+ assertTrue(result.isValid());
+ assertEquals(AxValidationResult.ValidationResult.OBSERVATION, result.getValidationResult());
+ assertNotNull(result.getMessageList());
+ assertNotNull("hello", result.toString());
+
+ AxValidationMessage vmess2 = new AxValidationMessage(AxArtifactKey.getNullKey(), AxArtifactKey.class,
+ ValidationResult.WARNING, "Some message");
+ result.addValidationMessage(vmess2);
+
+ assertFalse(result.isOk());
+ assertTrue(result.isValid());
+ assertEquals(AxValidationResult.ValidationResult.WARNING, result.getValidationResult());
+ assertNotNull(result.getMessageList());
+ assertNotNull("hello", result.toString());
+
+ AxValidationMessage vmess3 = new AxValidationMessage(AxArtifactKey.getNullKey(), AxArtifactKey.class,
+ ValidationResult.INVALID, "Some message");
+ result.addValidationMessage(vmess3);
+
+ assertFalse(result.isOk());
+ assertFalse(result.isValid());
+ assertEquals(AxValidationResult.ValidationResult.INVALID, result.getValidationResult());
+ assertNotNull(result.getMessageList());
+ assertNotNull("hello", result.toString());
+
+ assertEquals(AxValidationResult.ValidationResult.INVALID, result.getMessageList().get(3).getValidationResult());
+ assertEquals("Some message", result.getMessageList().get(3).getMessage());
+ assertEquals(AxArtifactKey.class.getName(), result.getMessageList().get(3).getObservedClass());
+ assertEquals(AxArtifactKey.getNullKey(), result.getMessageList().get(3).getObservedKey());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelExceptionTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelExceptionTest.java
new file mode 100644
index 000000000..2571ea65b
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelExceptionTest.java
@@ -0,0 +1,39 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import org.junit.Test;
+
+public class ApexModelExceptionTest {
+
+ @Test
+ public void test() {
+ assertNotNull(new ApexModelException("Message"));
+ assertNotNull(new ApexModelException("Message", new IOException()));
+
+ ApexModelException ame = new ApexModelException("Message", new IOException("IO exception message"));
+ assertEquals("Message\ncaused by: Message\ncaused by: IO exception message", ame.getCascadedMessage());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelFileWriterTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelFileWriterTest.java
new file mode 100644
index 000000000..0f8f956ab
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelFileWriterTest.java
@@ -0,0 +1,94 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+
+public class ApexModelFileWriterTest {
+
+ @Test
+ public void testModelFileWriter() throws IOException, ApexException {
+ ApexModelFileWriter<AxModel> modelFileWriter = new ApexModelFileWriter<>(true);
+
+ modelFileWriter.setValidate(true);
+ assertTrue(modelFileWriter.isValidate());
+
+ File tempFile = File.createTempFile("ApexFileWriterTest", "test");
+ File tempDir = tempFile.getParentFile();
+
+ File jsonTempFile = new File(tempDir.getAbsolutePath() + "/aaa/ApexFileWriterTest.json");
+
+ AxModel model = new DummyApexBasicModelCreator().getModel();
+
+ modelFileWriter.apexModelWriteJsonFile(model, AxModel.class, jsonTempFile.getAbsolutePath());
+
+ jsonTempFile.delete();
+ new File(tempDir.getAbsolutePath() + "/aaa").delete();
+ new File(tempDir.getAbsolutePath() + "/ccc").delete();
+
+ jsonTempFile = new File(tempDir.getAbsolutePath() + "/aaa/bbb/ApexFileWriterTest.json");
+
+ modelFileWriter.apexModelWriteJsonFile(model, AxModel.class, jsonTempFile.getAbsolutePath());
+
+ jsonTempFile.delete();
+
+ new File(tempDir.getAbsolutePath() + "/aaa/bbb").delete();
+ new File(tempDir.getAbsolutePath() + "/aaa").delete();
+ new File(tempDir.getAbsolutePath() + "/ccc/ddd").delete();
+ new File(tempDir.getAbsolutePath() + "/ccc").delete();
+
+ File dirA = new File(tempDir.getAbsolutePath() + "/aaa");
+ // File dirB = new File(tempDir.getAbsolutePath() + "/aaa/bbb");
+ dirA.createNewFile();
+ // dirB.createNewFile();
+
+ jsonTempFile = new File(tempDir.getAbsolutePath() + "/aaa/bbb/ApexFileWriterTest.json");
+ final File jsonTempFile01 = jsonTempFile;
+ assertThatThrownBy(
+ () -> modelFileWriter.apexModelWriteJsonFile(model, AxModel.class, jsonTempFile01.getAbsolutePath()))
+ .hasMessageContaining("could not create directory");
+
+ dirA.delete();
+
+ dirA = new File(tempDir.getAbsolutePath() + "/aaa");
+ File fileB = new File(tempDir.getAbsolutePath() + "/aaa/bbb");
+ dirA.mkdir();
+ fileB.createNewFile();
+
+ jsonTempFile = new File(tempDir.getAbsolutePath() + "/aaa/bbb/ApexFileWriterTest.json");
+
+ File jsonTempFile02 = jsonTempFile;
+ assertThatThrownBy(
+ () -> modelFileWriter.apexModelWriteJsonFile(model, AxModel.class, jsonTempFile02.getAbsolutePath()))
+ .hasMessageContaining("error processing file");
+
+ fileB.delete();
+ dirA.delete();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReaderTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReaderTest.java
new file mode 100644
index 000000000..1152771ea
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReaderTest.java
@@ -0,0 +1,105 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,2022 Nordix Foundation
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ApexModelReaderTest {
+ @Test
+ public void testModelReader() throws IOException, ApexException {
+ AxModel model = new DummyApexBasicModelCreator().getModel();
+ AxModel invalidModel = new DummyApexBasicModelCreator().getInvalidModel();
+
+ ApexModelWriter<AxModel> modelWriter = new ApexModelWriter<AxModel>(AxModel.class);
+ modelWriter.setValidate(true);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ modelWriter.write(model, baos);
+
+ ByteArrayOutputStream baosInvalid = new ByteArrayOutputStream();
+ modelWriter.setValidate(false);
+ modelWriter.write(invalidModel, baosInvalid);
+
+ ApexModelReader<AxModel> modelReader = new ApexModelReader<AxModel>(AxModel.class, true);
+
+ modelReader.setValidate(true);
+ assertTrue(modelReader.isValidate());
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ AxModel readModel = modelReader.read(bais);
+ assertEquals(model, readModel);
+
+ ByteArrayInputStream baisInvalid = new ByteArrayInputStream(baosInvalid.toByteArray());
+ assertThatThrownBy(() -> modelReader.read(baisInvalid))
+ .hasMessageStartingWith("Apex concept validation failed");
+ modelReader.setValidate(false);
+ assertFalse(modelReader.isValidate());
+
+ ByteArrayInputStream bais2 = new ByteArrayInputStream(baos.toByteArray());
+ AxModel readModel2 = modelReader.read(bais2);
+ assertEquals(model, readModel2);
+
+ ByteArrayOutputStream baosJson = new ByteArrayOutputStream();
+ modelWriter.write(model, baosJson);
+
+ ByteArrayInputStream baisJson = new ByteArrayInputStream(baosJson.toByteArray());
+ AxModel readModelJson = modelReader.read(baisJson);
+ assertEquals(model, readModelJson);
+
+ String dummyString = "SomeDummyText";
+ ByteArrayInputStream baisDummy = new ByteArrayInputStream(dummyString.getBytes());
+ assertThatThrownBy(() -> modelReader.read(baisDummy))
+ .hasMessageContaining("Unable to unmarshal Apex concept");
+ ByteArrayInputStream nullBais = null;
+ assertThatThrownBy(() -> modelReader.read(nullBais))
+ .hasMessage("concept stream may not be null");
+
+ assertThatThrownBy(() -> {
+ FileInputStream fis = new FileInputStream(new File("somewhere/over/the/rainbow"));
+ modelReader.read(fis);
+ }).hasMessageContaining("rainbow");
+ final File tempFile = File.createTempFile("Apex", "Dummy");
+ BufferedReader br = new BufferedReader(new FileReader(tempFile));
+ br.close();
+ assertThatThrownBy(() -> modelReader.read(br))
+ .hasMessage("Unable to read Apex concept ");
+ tempFile.delete();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelSaverTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelSaverTest.java
new file mode 100644
index 000000000..c95106aa8
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelSaverTest.java
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+
+public class ApexModelSaverTest {
+
+ @Test
+ public void testModelSaver() throws IOException, ApexException {
+ AxModel model = new DummyApexBasicModelCreator().getModel();
+ assertNotNull(model);
+
+ Path tempPath = Files.createTempDirectory("ApexTest");
+ assertNotNull(tempPath);
+
+ ApexModelSaver<AxModel> modelSaver =
+ new ApexModelSaver<AxModel>(AxModel.class, model, tempPath.toAbsolutePath().toString());
+ assertNotNull(modelSaver);
+ modelSaver.apexModelWriteJson();
+
+ Files.deleteIfExists(new File(tempPath.toAbsolutePath() + "/BasicModel.json").toPath());
+ Files.deleteIfExists(tempPath);
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelStringWriterTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelStringWriterTest.java
new file mode 100644
index 000000000..13e72d3e2
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelStringWriterTest.java
@@ -0,0 +1,63 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+
+public class ApexModelStringWriterTest {
+
+ @Test
+ public void testModelStringWriter() throws IOException, ApexException {
+ AxModel basicModel = new DummyApexBasicModelCreator().getModel();
+ assertNotNull(basicModel);
+
+ AxKeyInfo intKeyInfo = basicModel.getKeyInformation().get("IntegerKIKey");
+ AxKeyInfo floatKeyInfo = basicModel.getKeyInformation().get("FloatKIKey");
+
+ // Ensure marshalling is OK
+ ApexModelStringWriter<AxKeyInfo> stringWriter = new ApexModelStringWriter<AxKeyInfo>(true);
+
+ assertNotNull(stringWriter.writeJsonString(intKeyInfo, AxKeyInfo.class));
+ assertNotNull(stringWriter.writeJsonString(floatKeyInfo, AxKeyInfo.class));
+
+ assertNotNull(stringWriter.writeString(intKeyInfo, AxKeyInfo.class));
+ assertNotNull(stringWriter.writeString(floatKeyInfo, AxKeyInfo.class));
+
+ assertNotNull(stringWriter.writeString(intKeyInfo, AxKeyInfo.class));
+ assertNotNull(stringWriter.writeString(floatKeyInfo, AxKeyInfo.class));
+
+ assertThatThrownBy(() -> stringWriter.writeString(null, AxKeyInfo.class)).hasMessage("concept may not be null");
+ assertThatThrownBy(() -> stringWriter.writeString(null, AxKeyInfo.class)).hasMessage("concept may not be null");
+ assertThatThrownBy(() -> stringWriter.writeJsonString(null, AxKeyInfo.class))
+ .hasMessage("error writing JSON string");
+ stringWriter.setValidate(true);
+ assertTrue(stringWriter.isValidate());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriterTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriterTest.java
new file mode 100644
index 000000000..063855976
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriterTest.java
@@ -0,0 +1,67 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,2022 Nordix Foundation
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ApexModelWriterTest {
+ @Test
+ public void testModelWriter() throws IOException, ApexException {
+ ApexModelWriter<AxModel> modelWriter = new ApexModelWriter<AxModel>(AxModel.class);
+
+ modelWriter.setValidate(true);
+ assertTrue(modelWriter.isValidate());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ AxModel model = new DummyApexBasicModelCreator().getModel();
+
+ modelWriter.write(model, baos);
+
+ modelWriter.setValidate(false);
+ modelWriter.write(model, baos);
+
+ modelWriter.setValidate(true);
+ model.getKeyInformation().getKeyInfoMap().clear();
+ assertThatThrownBy(() -> modelWriter.write(model, baos))
+ .hasMessageContaining("Apex concept (BasicModel:0.0.1) validation failed");
+ model.getKeyInformation().generateKeyInfo(model);
+
+ assertThatThrownBy(() -> modelWriter.write(null, baos))
+ .hasMessage("concept may not be null");
+
+ ByteArrayOutputStream nullBaos = null;
+ assertThatThrownBy(() -> modelWriter.write(model, nullBaos))
+ .hasMessage("concept stream may not be null");
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/DummyApexBasicModelCreator.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/DummyApexBasicModelCreator.java
new file mode 100644
index 000000000..353722b2d
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/DummyApexBasicModelCreator.java
@@ -0,0 +1,123 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import java.util.UUID;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+
+public class DummyApexBasicModelCreator implements TestApexModelCreator<AxModel> {
+
+ @Override
+ public AxModel getModel() {
+ AxModel basicModel = new AxModel();
+
+ basicModel.setKey(new AxArtifactKey("BasicModel", "0.0.1"));
+ basicModel.setKeyInformation(new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1")));
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKey(), new AxKeyInfo(basicModel.getKey()));
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKeyInformation().getKey(),
+ new AxKeyInfo(basicModel.getKeyInformation().getKey()));
+
+ AxKeyInfo intKeyInfo = new AxKeyInfo(new AxArtifactKey("IntegerKIKey", "0.0.1"), UUID.randomUUID(),
+ "IntegerKIKey description");
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKeyInfo.getKey(), new AxKeyInfo(intKeyInfo.getKey()));
+
+ AxKeyInfo floatKeyInfo = new AxKeyInfo(new AxArtifactKey("FloatKIKey", "0.0.1"), UUID.randomUUID(),
+ "FloatKIKey description");
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKeyInfo.getKey(), new AxKeyInfo(floatKeyInfo.getKey()));
+
+ return basicModel;
+ }
+
+ @Override
+ public final AxModel getMalstructuredModel() {
+ AxModel basicModel = new AxModel();
+
+ // Note: No Data types
+ basicModel.setKey(new AxArtifactKey("BasicModelKey", "0.0.1"));
+ basicModel.setKeyInformation(new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1")));
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKey(), new AxKeyInfo(basicModel.getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000000"),
+ "\nbasic model description\nThis is a multi line description\nwith another line of text."));
+
+ return basicModel;
+ }
+
+ @Override
+ public final AxModel getObservationModel() {
+ AxModel basicModel = getModel();
+
+ // Set key information as blank
+ basicModel.getKeyInformation().getKeyInfoMap().get(basicModel.getKey()).setDescription("");
+
+ return basicModel;
+ }
+
+ @Override
+ public final AxModel getWarningModel() {
+ AxModel basicModel = getModel();
+
+ // Add unreferenced key information
+ AxKeyInfo unreferencedKeyInfo0 = new AxKeyInfo(new AxArtifactKey("Unref0", "0.0.1"));
+ AxKeyInfo unreferencedKeyInfo1 = new AxKeyInfo(new AxArtifactKey("Unref1", "0.0.1"));
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(unreferencedKeyInfo0.getKey(), unreferencedKeyInfo0);
+ basicModel.getKeyInformation().getKeyInfoMap().put(unreferencedKeyInfo1.getKey(), unreferencedKeyInfo1);
+
+ return basicModel;
+ }
+
+ @Override
+ public final AxModel getInvalidModel() {
+ AxModel basicModel = new AxModel();
+
+ basicModel.setKey(new AxArtifactKey("BasicModelKey", "0.0.1"));
+ basicModel.setKeyInformation(new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1")));
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKey(), new AxKeyInfo(basicModel.getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000000"),
+ "nbasic model description\nThis is a multi line description\nwith another line of text."));
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKeyInformation().getKey(),
+ new AxKeyInfo(basicModel.getKeyInformation().getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000000"), ""));
+
+ return basicModel;
+ }
+
+ /**
+ * Get the model with its references.
+ * @return the model with its references
+ */
+ public final DummyAxModelWithReferences getModelWithReferences() {
+ AxModel model = getModel();
+
+ DummyAxModelWithReferences modelWithReferences = new DummyAxModelWithReferences(model.getKey());
+ modelWithReferences.setKeyInformation(model.getKeyInformation());
+ modelWithReferences.setReferenceKeyList();
+
+ return modelWithReferences;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/DummyAxModelWithReferences.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/DummyAxModelWithReferences.java
new file mode 100644
index 000000000..887755d03
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/DummyAxModelWithReferences.java
@@ -0,0 +1,71 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+public class DummyAxModelWithReferences extends AxModel {
+ private static final long serialVersionUID = -8194956638511120008L;
+
+ private List<AxKey> extrakeyList = new ArrayList<>();
+
+ public DummyAxModelWithReferences(final AxArtifactKey key) {
+ super(key);
+ }
+
+ @Override
+ public List<AxKey> getKeys() {
+ List<AxKey> keys = super.getKeys();
+ keys.addAll(extrakeyList);
+
+ return keys;
+ }
+
+ public List<AxKey> getExtrakeyList() {
+ return extrakeyList;
+ }
+
+ /**
+ * Set the reference key list.
+ */
+ public void setReferenceKeyList() {
+ List<AxKey> keys = super.getKeys();
+
+ for (AxKey key: keys) {
+ AxArtifactKey akey = (AxArtifactKey) key;
+ AxReferenceKey keyRef = new AxReferenceKey(akey, akey.getName());
+ extrakeyList.add(keyRef);
+ }
+ }
+
+ public void addKey(final AxKey akey) {
+ extrakeyList.add(akey);
+ }
+
+ public void removeKey(final AxKey akey) {
+ extrakeyList.remove(akey);
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexBasicModelConceptsTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexBasicModelConceptsTest.java
new file mode 100644
index 000000000..905a27f38
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexBasicModelConceptsTest.java
@@ -0,0 +1,294 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2021 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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModel;
+
+public class SupportApexBasicModelConceptsTest {
+ TestApexModel<AxModel> testApexModel;
+
+ @Before
+ public void setup() throws Exception {
+ testApexModel = new TestApexModel<AxModel>(AxModel.class, new DummyApexBasicModelCreator());
+ }
+
+ @Test
+ public void testModelConcepts() {
+ final AxModel model = testApexModel.getModel();
+ assertNotNull(model);
+ model.clean();
+ assertNotNull(model);
+
+ AxValidationResult result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.WARNING, result.getValidationResult());
+
+ model.register();
+ assertEquals(model.getKeyInformation(), ModelService.getModel(AxKeyInformation.class));
+
+ final AxModel clonedModel = new AxModel(model);
+ assertTrue(clonedModel.toString().startsWith("AxModel:(key=AxArtifactKey:(name=BasicModel"));
+
+ assertNotEquals(0, model.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(model, model); // NOSONAR
+ assertEquals(model, clonedModel);
+ assertNotNull(model);
+ assertNotEquals(model, (Object) "Hello");
+ clonedModel.getKey().setVersion("0.0.2");
+ assertNotEquals(model, clonedModel);
+ clonedModel.getKey().setVersion("0.0.1");
+
+ assertEquals(0, model.compareTo(model));
+ assertNotEquals(0, model.compareTo(null));
+ assertNotEquals(0, model.compareTo(new AxReferenceKey()));
+ assertEquals(0, model.compareTo(clonedModel));
+ clonedModel.getKey().setVersion("0.0.2");
+ assertNotEquals(0, model.compareTo(clonedModel));
+ clonedModel.getKey().setVersion("0.0.1");
+
+ assertNotNull(model.getKeys());
+
+ model.getKeyInformation().generateKeyInfo(model);
+ assertNotNull(model.getKeyInformation());
+
+ }
+
+ @Test
+ public void testKeyInformation() {
+
+ final AxModel model = testApexModel.getModel();
+ final AxKeyInformation keyI = model.getKeyInformation();
+ final AxKeyInformation clonedKeyI = new AxKeyInformation(keyI);
+
+ assertNotNull(keyI);
+ assertNotEquals(keyI, (Object) new AxArtifactKey());
+ assertEquals(keyI, clonedKeyI);
+
+ clonedKeyI.setKey(new AxArtifactKey());
+ assertNotEquals(keyI, clonedKeyI);
+ clonedKeyI.setKey(keyI.getKey());
+
+ assertEquals(0, keyI.compareTo(keyI));
+ assertEquals(0, keyI.compareTo(clonedKeyI));
+ assertNotEquals(0, keyI.compareTo(null));
+ assertNotEquals(0, keyI.compareTo(new AxArtifactKey()));
+
+ clonedKeyI.setKey(new AxArtifactKey());
+ assertNotEquals(0, keyI.compareTo(clonedKeyI));
+ clonedKeyI.setKey(keyI.getKey());
+ assertEquals(0, keyI.compareTo(clonedKeyI));
+
+ clonedKeyI.getKeyInfoMap().clear();
+ assertNotEquals(0, keyI.compareTo(clonedKeyI));
+
+ AxKeyInfo keyInfo = keyI.get("BasicModel");
+ assertNotNull(keyInfo);
+
+ keyInfo = keyI.get(new AxArtifactKey("BasicModel", "0.0.1"));
+ assertNotNull(keyInfo);
+
+ Set<AxKeyInfo> keyInfoSet = keyI.getAll("BasicModel");
+ assertNotNull(keyInfoSet);
+
+ keyInfoSet = keyI.getAll("BasicModel", "0..0.1");
+ assertNotNull(keyInfoSet);
+
+ List<AxKey> keys = model.getKeys();
+ assertNotEquals(0, keys.size());
+
+ keys = keyI.getKeys();
+ assertNotEquals(0, keys.size());
+
+ model.getKeyInformation().generateKeyInfo(model);
+ assertNotNull(model.getKeyInformation());
+ model.getKeyInformation().getKeyInfoMap().clear();
+ model.getKeyInformation().generateKeyInfo(model);
+ assertNotNull(model.getKeyInformation());
+ }
+
+ @Test
+ public void testClonedKey() {
+ final AxModel model = testApexModel.getModel();
+ final AxKeyInformation keyI = model.getKeyInformation();
+ final AxKeyInformation clonedKeyI = new AxKeyInformation(keyI);
+ AxValidationResult result = new AxValidationResult();
+
+ clonedKeyI.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ clonedKeyI.setKey(keyI.getKey());
+
+ clonedKeyI.getKeyInfoMap().clear();
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ clonedKeyI.generateKeyInfo(model);
+
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ clonedKeyI.getKeyInfoMap().put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ clonedKeyI.getKeyInfoMap().clear();
+ clonedKeyI.generateKeyInfo(model);
+
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ clonedKeyI.getKeyInfoMap().put(new AxArtifactKey("SomeKey", "0.0.1"), null);
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ clonedKeyI.getKeyInfoMap().clear();
+ clonedKeyI.generateKeyInfo(model);
+
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxKeyInfo mk = clonedKeyI.get(new AxArtifactKey("BasicModel", "0.0.1"));
+ assertNotNull(mk);
+ mk.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ clonedKeyI.getKeyInfoMap().clear();
+ clonedKeyI.generateKeyInfo(model);
+
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxModel clonedModel = new AxModel(model);
+ clonedModel.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = clonedModel.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ clonedModel.setKey(model.getKey());
+ result = new AxValidationResult();
+ result = clonedKeyI.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+ }
+
+ @Test
+ public void testModelConceptsWithReferences() {
+ final DummyAxModelWithReferences mwr = new DummyApexBasicModelCreator().getModelWithReferences();
+ assertNotNull(mwr);
+ mwr.getKeyInformation().getKeyInfoMap().clear();
+ mwr.getKeyInformation().generateKeyInfo(mwr);
+
+ AxValidationResult result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Duplicate key error
+ mwr.addKey(mwr.getKey());
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ mwr.removeKey(mwr.getKey());
+
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Null Reference Key
+ mwr.addKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ mwr.removeKey(AxReferenceKey.getNullKey());
+
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Duplicate Reference Key
+ final AxReferenceKey rKey = new AxReferenceKey(mwr.getKey(), "LocalName");
+ mwr.addKey(rKey);
+ mwr.addKey(rKey);
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ mwr.removeKey(rKey);
+ mwr.removeKey(rKey);
+
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Key Use is legal
+ final AxKeyUse keyU = new AxKeyUse(mwr.getKey());
+ mwr.addKey(keyU);
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+ mwr.removeKey(keyU);
+
+ // Key Use on bad artifact key
+ final AxKeyUse keyBadUsage = new AxKeyUse(new AxArtifactKey("SomeKey", "0.0.1"));
+ mwr.addKey(keyBadUsage);
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ mwr.removeKey(keyBadUsage);
+
+ // Key Use on bad reference key
+ final AxKeyUse keyBadReferenceUsage = new AxKeyUse(new AxReferenceKey("SomeKey", "0.0.1", "Local"));
+ mwr.addKey(keyBadReferenceUsage);
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ mwr.removeKey(keyBadReferenceUsage);
+
+ result = new AxValidationResult();
+ result = mwr.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexBasicModelTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexBasicModelTest.java
new file mode 100644
index 000000000..68f755886
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexBasicModelTest.java
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020-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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModel;
+
+public class SupportApexBasicModelTest {
+ // As there are no real concepts in a basic model, this is as near to a valid model as we can get
+ private static final String VALID_MODEL_STRING = "\n" + "***warnings issued during validation of model***\n"
+ + "AxArtifactKey:(name=FloatKIKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts"
+ + ".AxModel:WARNING:key not found for key information entry\n"
+ + "AxArtifactKey:(name=IntegerKIKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts"
+ + ".AxModel:WARNING:key not found for key information entry\n" + "********************************";
+
+ private static final String WARNING_MODEL_STRING = "\n" + "***warnings issued during validation of model***\n"
+ + "AxArtifactKey:(name=FloatKIKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts"
+ + ".AxModel:WARNING:key not found for key information entry\n"
+ + "AxArtifactKey:(name=IntegerKIKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts"
+ + ".AxModel:WARNING:key not found for key information entry\n"
+ + "AxArtifactKey:(name=Unref0,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts"
+ + ".AxModel:WARNING:key not found for key information entry\n"
+ + "AxArtifactKey:(name=Unref1,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts"
+ + ".AxModel:WARNING:key not found for key information entry\n" + "********************************";
+
+ private static final String INVALID_MODEL_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=BasicModelKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts."
+ + "AxKeyInfo:WARNING:UUID is a zero UUID: 00000000-0000-0000-0000-000000000000\n"
+ + "AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts."
+ + "AxKeyInfo:OBSERVATION:description is blank\n"
+ + "AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts."
+ + "AxKeyInfo:WARNING:UUID is a zero UUID: 00000000-0000-0000-0000-000000000000\n"
+ + "AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts."
+ + "AxKeyInformation:INVALID:duplicate UUID found on keyInfoMap entry AxArtifactKey:"
+ + "(name=KeyInfoMapKey,version=0.0.1):00000000-0000-0000-0000-000000000000\n"
+ + "********************************";
+
+ private static final String INVALID_MODEL_MALSTRUCTURED_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=BasicModelKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts."
+ + "AxKeyInfo:WARNING:UUID is a zero UUID: 00000000-0000-0000-0000-000000000000\n"
+ + "AxArtifactKey:(name=BasicModelKey,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts."
+ + "AxModel:INVALID:key information not found for key "
+ + "AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1)\n" + "********************************";
+
+ TestApexModel<AxModel> testApexModel;
+
+ /**
+ * Set up the test.
+ *
+ * @throws Exception any exception thrown by the test
+ */
+ @Before
+ public void setup() throws Exception {
+ testApexModel = new TestApexModel<AxModel>(AxModel.class, new DummyApexBasicModelCreator());
+ }
+
+ @Test
+ public void testModelValid() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelValid();
+ assertEquals(VALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testApexModelVaidateObservation() throws Exception {
+ assertThatThrownBy(testApexModel::testApexModelVaidateObservation)
+ .hasMessage("model should have observations");
+ }
+
+ @Test
+ public void testApexModelVaidateWarning() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateWarning();
+ assertEquals(WARNING_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateInvalidModel() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateInvalidModel();
+ assertEquals(INVALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateMalstructured() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateMalstructured();
+ assertEquals(INVALID_MODEL_MALSTRUCTURED_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelWriteReadJson() throws Exception {
+ testApexModel.testApexModelWriteReadJson();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator0.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator0.java
new file mode 100644
index 000000000..e835bc0fc
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator0.java
@@ -0,0 +1,64 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+
+public class SupportApexModelCreator0 implements TestApexModelCreator<AxModel> {
+
+ @Override
+ public AxModel getModel() {
+ AxModel basicModel = new AxModel();
+
+ basicModel.setKey(new AxArtifactKey("BasicModel", "0.0.1"));
+ basicModel.setKeyInformation(new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1")));
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKey(), new AxKeyInfo(basicModel.getKey()));
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKeyInformation().getKey(),
+ new AxKeyInfo(basicModel.getKeyInformation().getKey()));
+
+ return basicModel;
+ }
+
+ @Override
+ public final AxModel getMalstructuredModel() {
+ return getModel();
+ }
+
+ @Override
+ public final AxModel getObservationModel() {
+ return getModel();
+ }
+
+ @Override
+ public final AxModel getWarningModel() {
+ return getModel();
+ }
+
+ @Override
+ public final AxModel getInvalidModel() {
+ return getModel();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator1.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator1.java
new file mode 100644
index 000000000..9ad34a38c
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator1.java
@@ -0,0 +1,68 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import java.util.UUID;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+
+public class SupportApexModelCreator1 implements TestApexModelCreator<AxModel> {
+
+ @Override
+ public AxModel getModel() {
+ return getInvalidModel();
+ }
+
+ @Override
+ public final AxModel getMalstructuredModel() {
+ return getInvalidModel();
+ }
+
+ @Override
+ public final AxModel getObservationModel() {
+ return getInvalidModel();
+ }
+
+ @Override
+ public final AxModel getWarningModel() {
+ return getInvalidModel();
+ }
+
+ @Override
+ public final AxModel getInvalidModel() {
+ AxModel basicModel = new AxModel();
+
+ basicModel.setKey(new AxArtifactKey("BasicModelKey", "0.0.1"));
+ basicModel.setKeyInformation(new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1")));
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKey(), new AxKeyInfo(basicModel.getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000000"),
+ "nbasic model description\nThis is a multi line description\nwith another line of text."));
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKeyInformation().getKey(),
+ new AxKeyInfo(basicModel.getKeyInformation().getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000000"), ""));
+
+ return basicModel;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator2.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator2.java
new file mode 100644
index 000000000..0ab7aab7f
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportApexModelCreator2.java
@@ -0,0 +1,64 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.basicmodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+
+public class SupportApexModelCreator2 implements TestApexModelCreator<AxModel> {
+
+ @Override
+ public AxModel getModel() {
+ AxModel basicModel = new AxModel();
+
+ basicModel.setKey(new AxArtifactKey("BasicModel", "0.0.1"));
+ basicModel.setKeyInformation(new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1")));
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKey(), new AxKeyInfo(basicModel.getKey()));
+ basicModel.getKeyInformation().getKeyInfoMap().put(basicModel.getKeyInformation().getKey(),
+ new AxKeyInfo(basicModel.getKeyInformation().getKey()));
+ basicModel.getKeyInformation().get("BasicModel").setDescription("");
+ return basicModel;
+ }
+
+ @Override
+ public final AxModel getMalstructuredModel() {
+ return getModel();
+ }
+
+ @Override
+ public final AxModel getObservationModel() {
+ return getModel();
+ }
+
+ @Override
+ public final AxModel getWarningModel() {
+ return getModel();
+ }
+
+ @Override
+ public final AxModel getInvalidModel() {
+ return getModel();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportBasicModelTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportBasicModelTest.java
new file mode 100644
index 000000000..d55a9da29
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportBasicModelTest.java
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020-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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModel;
+
+public class SupportBasicModelTest {
+
+ @Test
+ public void testNormalModelCreator() throws ApexException {
+ final TestApexModel<AxModel> testApexModel = new TestApexModel<AxModel>(AxModel.class,
+ new DummyApexBasicModelCreator());
+
+ testApexModel.testApexModelValid();
+ assertThatThrownBy(testApexModel::testApexModelVaidateObservation)
+ .hasMessage("model should have observations");
+ testApexModel.testApexModelVaidateWarning();
+ testApexModel.testApexModelVaidateInvalidModel();
+ testApexModel.testApexModelVaidateMalstructured();
+
+ testApexModel.testApexModelWriteReadJson();
+ }
+
+ @Test
+ public void testModelsUnequal() throws ApexException {
+ final TestApexModel<AxModel> testApexModel0 = new TestApexModel<AxModel>(AxModel.class,
+ new DummyApexBasicModelCreator());
+ final TestApexModel<AxModel> testApexModel1 = new TestApexModel<AxModel>(AxModel.class,
+ new DummyApexBasicModelCreator());
+
+ testApexModel1.getModel().getKey().setVersion("0.0.2");
+
+ assertThatThrownBy(() -> testApexModel0.checkModelEquality(testApexModel0.getModel(), testApexModel1.getModel(),
+ "Models are not equal")).hasMessage("Models are not equal");
+ }
+
+ @Test
+ public void testModelCreator0() throws ApexException {
+ final TestApexModel<AxModel> testApexModel = new TestApexModel<AxModel>(AxModel.class,
+ new SupportApexModelCreator0());
+
+ testApexModel.testApexModelValid();
+ assertThatThrownBy(() -> testApexModel.testApexModelVaidateObservation())
+ .hasMessage("model should have observations");
+ assertThatThrownBy(() -> testApexModel.testApexModelVaidateWarning())
+ .hasMessage("model should have warnings");
+ assertThatThrownBy(() -> testApexModel.testApexModelVaidateInvalidModel())
+ .hasMessage("model should not be valid ***validation of model successful***");
+ assertThatThrownBy(() -> testApexModel.testApexModelVaidateMalstructured())
+ .hasMessage("model should not be valid ***validation of model successful***");
+ }
+
+ @Test
+ public void testModelCreator1() throws ApexException {
+ final TestApexModel<AxModel> testApexModel = new TestApexModel<AxModel>(AxModel.class,
+ new SupportApexModelCreator1());
+
+ assertThatThrownBy(() -> testApexModel.testApexModelValid())
+ .hasMessageStartingWith("model is invalid");
+ assertThatThrownBy(() -> testApexModel.testApexModelVaidateObservation())
+ .hasMessageStartingWith("model is invalid");
+ assertThatThrownBy(() -> testApexModel.testApexModelVaidateWarning())
+ .hasMessageStartingWith("model is invalid");
+ testApexModel.testApexModelVaidateInvalidModel();
+ testApexModel.testApexModelVaidateMalstructured();
+ }
+
+ @Test
+ public void testModelCreator2() throws ApexException {
+ final TestApexModel<AxModel> testApexModel = new TestApexModel<AxModel>(AxModel.class,
+ new SupportApexModelCreator2());
+
+ testApexModel.testApexModelValid();
+ testApexModel.testApexModelVaidateObservation();
+ assertThatThrownBy(() -> testApexModel.testApexModelVaidateWarning())
+ .hasMessage("model should have warnings");
+ }
+
+ @Test
+ public void testModelCreator1Json() throws ApexException {
+ final TestApexModel<AxModel> testApexModel = new TestApexModel<AxModel>(AxModel.class,
+ new SupportApexModelCreator1());
+
+ assertThatThrownBy(() -> testApexModel.testApexModelWriteReadJson())
+ .hasMessageStartingWith("error processing file");
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportConceptGetterTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportConceptGetterTest.java
new file mode 100644
index 000000000..1783fc00f
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/SupportConceptGetterTest.java
@@ -0,0 +1,217 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020-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.onap.policy.apex.model.basicmodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.UUID;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+
+public class SupportConceptGetterTest {
+
+ private static final AxKeyInfo intKI01 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey01", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey01 description");
+ private static final AxKeyInfo intKI11 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey11", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey11 description");
+ private static final AxKeyInfo intKI21 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey21", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey21 description");
+ private static final AxKeyInfo intKI22 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey22", "0.0.2"),
+ UUID.randomUUID(), "IntegerKIKey22 description");
+ private static final AxKeyInfo intKI23 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey23", "0.0.3"),
+ UUID.randomUUID(), "IntegerKIKey23 description");
+ private static final AxKeyInfo intKI24 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey24", "0.0.4"),
+ UUID.randomUUID(), "IntegerKIKey24 description");
+ private static final AxKeyInfo intKI25 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey25", "0.0.5"),
+ UUID.randomUUID(), "IntegerKIKey25 description");
+ private static final AxKeyInfo intKI26 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey26", "0.0.6"),
+ UUID.randomUUID(), "IntegerKIKey26 description");
+ private static final AxKeyInfo intKI31 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey31", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey31 description");
+ private static final AxKeyInfo intKI41 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey41", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey41 description");
+ private static final AxKeyInfo intKI51 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey51", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey51 description");
+ private static final AxKeyInfo intKI52 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey52", "0.0.2"),
+ UUID.randomUUID(), "IntegerKIKey52 description");
+ private static final AxKeyInfo intKI53 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey53", "0.0.3"),
+ UUID.randomUUID(), "IntegerKIKey53 description");
+ private static final AxKeyInfo intKI54 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey54", "0.0.4"),
+ UUID.randomUUID(), "IntegerKIKey54 description");
+ private static final AxKeyInfo intKI61 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey61", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey61 description");
+ private static final AxKeyInfo intKI62 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey62", "0.0.2"),
+ UUID.randomUUID(), "IntegerKIKey62 description");
+ private static final AxKeyInfo intKI63 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey63", "0.0.3"),
+ UUID.randomUUID(), "IntegerKIKey63 description");
+ private static final AxKeyInfo intKI64 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey64", "0.0.4"),
+ UUID.randomUUID(), "IntegerKIKey64 description");
+ private static final AxKeyInfo intKI71 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey71", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey71 description");
+ private static final AxKeyInfo intKI81 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey81", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey81 description");
+ private static final AxKeyInfo intKI91 = new AxKeyInfo(new AxArtifactKey("IntegerKIKey91", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey91 description");
+ private static final AxKeyInfo floatKI01 = new AxKeyInfo(new AxArtifactKey("FloatKIKey01", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey01 description");
+ private static final AxKeyInfo floatKI11 = new AxKeyInfo(new AxArtifactKey("FloatKIKey11", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey11 description");
+ private static final AxKeyInfo floatKI21 = new AxKeyInfo(new AxArtifactKey("FloatKIKey21", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey21 description");
+ private static final AxKeyInfo floatKI31 = new AxKeyInfo(new AxArtifactKey("FloatKIKey31", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey31 description");
+ private static final AxKeyInfo floatKI41 = new AxKeyInfo(new AxArtifactKey("FloatKIKey41", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey41 description");
+ private static final AxKeyInfo floatKI51 = new AxKeyInfo(new AxArtifactKey("FloatKIKey51", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey51 description");
+ private static final AxKeyInfo floatKI61 = new AxKeyInfo(new AxArtifactKey("FloatKIKey61", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey61 description");
+ private static final AxKeyInfo floatKI71 = new AxKeyInfo(new AxArtifactKey("FloatKIKey71", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey71 description");
+ private static final AxKeyInfo floatKI81 = new AxKeyInfo(new AxArtifactKey("FloatKIKey81", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey81 description");
+ private static final AxKeyInfo floatKI82 = new AxKeyInfo(new AxArtifactKey("FloatKIKey82", "0.0.2"),
+ UUID.randomUUID(), "IntegerKIKey82 description");
+ private static final AxKeyInfo floatKI83 = new AxKeyInfo(new AxArtifactKey("FloatKIKey83", "0.0.3"),
+ UUID.randomUUID(), "IntegerKIKey83 description");
+ private static final AxKeyInfo floatKI91 = new AxKeyInfo(new AxArtifactKey("FloatKIKey91", "0.0.1"),
+ UUID.randomUUID(), "IntegerKIKey91 description");
+ private static final AxKeyInfo floatKI92 = new AxKeyInfo(new AxArtifactKey("FloatKIKey92", "0.0.2"),
+ UUID.randomUUID(), "IntegerKIKey92 description");
+ private static final AxKeyInfo floatKI93 = new AxKeyInfo(new AxArtifactKey("FloatKIKey93", "0.0.3"),
+ UUID.randomUUID(), "IntegerKIKey93 description");
+
+ @Test
+ public void testConceptGetterInteger() {
+ AxModel basicModel = setTestBasicModel();
+
+ assertNull(basicModel.getKeyInformation().get("NonExistantKey", "0.0.6"));
+ assertEquals(intKI26, basicModel.getKeyInformation().get("IntegerKIKey26", "0.0.6"));
+ assertEquals(intKI62, basicModel.getKeyInformation().get("IntegerKIKey62", "0.0.2"));
+ assertEquals(intKI21, basicModel.getKeyInformation().get("IntegerKIKey21", "0.0.1"));
+ assertEquals(intKI61, basicModel.getKeyInformation().get("IntegerKIKey61", "0.0.1"));
+
+ assertNull(basicModel.getKeyInformation().get("NonExistantKey"));
+
+ assertEquals(intKI01, basicModel.getKeyInformation().get("IntegerKIKey01"));
+ assertEquals(intKI11, basicModel.getKeyInformation().get("IntegerKIKey11"));
+ assertEquals(intKI26, basicModel.getKeyInformation().get("IntegerKIKey26"));
+ assertEquals(intKI31, basicModel.getKeyInformation().get("IntegerKIKey31"));
+ assertEquals(intKI41, basicModel.getKeyInformation().get("IntegerKIKey41"));
+ assertEquals(intKI54, basicModel.getKeyInformation().get("IntegerKIKey54"));
+ assertEquals(intKI64, basicModel.getKeyInformation().get("IntegerKIKey64"));
+ assertEquals(intKI71, basicModel.getKeyInformation().get("IntegerKIKey71"));
+ assertEquals(intKI81, basicModel.getKeyInformation().get("IntegerKIKey81"));
+ assertEquals(intKI91, basicModel.getKeyInformation().get("IntegerKIKey91"));
+ }
+
+ @Test
+ public void testConceptGetterFloat() {
+ AxModel basicModel = setTestBasicModel();
+
+ assertEquals(floatKI01, basicModel.getKeyInformation().get("FloatKIKey01"));
+ assertEquals(floatKI11, basicModel.getKeyInformation().get("FloatKIKey11"));
+ assertEquals(floatKI21, basicModel.getKeyInformation().get("FloatKIKey21"));
+ assertEquals(floatKI31, basicModel.getKeyInformation().get("FloatKIKey31"));
+ assertEquals(floatKI41, basicModel.getKeyInformation().get("FloatKIKey41"));
+ assertEquals(floatKI51, basicModel.getKeyInformation().get("FloatKIKey51"));
+ assertEquals(floatKI61, basicModel.getKeyInformation().get("FloatKIKey61"));
+ assertEquals(floatKI71, basicModel.getKeyInformation().get("FloatKIKey71"));
+ assertEquals(floatKI83, basicModel.getKeyInformation().get("FloatKIKey83"));
+ assertEquals(floatKI93, basicModel.getKeyInformation().get("FloatKIKey93"));
+ }
+
+ @Test
+ public void testMarshalling() throws IOException, ApexException {
+ AxModel basicModel = setTestBasicModel();
+
+ // Ensure marshalling and unmarshalling is OK
+ ApexModelReader<AxModel> modelReader = new ApexModelReader<AxModel>(AxModel.class);
+ ApexModelFileWriter<AxModel> modelWriter = new ApexModelFileWriter<AxModel>(true);
+
+ modelReader.setValidate(false);
+ modelWriter.setValidate(false);
+
+ File tempJsonFile = File.createTempFile("ApexModel", "json");
+ modelWriter.apexModelWriteJsonFile(basicModel, AxModel.class, tempJsonFile.getCanonicalPath());
+
+ FileInputStream jsonFileInputStream = new FileInputStream(tempJsonFile);
+ AxModel readJsonModel = modelReader.read(jsonFileInputStream);
+ jsonFileInputStream.close();
+ assertEquals(basicModel, readJsonModel);
+ assertEquals(intKI91, readJsonModel.getKeyInformation().get("IntegerKIKey91"));
+ assertNotNull(readJsonModel.getKeyInformation().get("FloatKIKey"));
+ tempJsonFile.delete();
+ }
+
+ private AxModel setTestBasicModel() {
+ AxModel basicModel = new DummyApexBasicModelCreator().getModel();
+ assertNotNull(basicModel);
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI31.getKey(), intKI31);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI24.getKey(), intKI24);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI11.getKey(), intKI11);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI64.getKey(), intKI64);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI41.getKey(), intKI41);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI51.getKey(), intKI51);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI23.getKey(), intKI23);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI81.getKey(), intKI81);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI71.getKey(), intKI71);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI01.getKey(), intKI01);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI91.getKey(), intKI91);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI52.getKey(), intKI52);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI53.getKey(), intKI53);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI62.getKey(), intKI62);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI54.getKey(), intKI54);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI26.getKey(), intKI26);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI22.getKey(), intKI22);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI25.getKey(), intKI25);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI21.getKey(), intKI21);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI61.getKey(), intKI61);
+ basicModel.getKeyInformation().getKeyInfoMap().put(intKI63.getKey(), intKI63);
+
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI11.getKey(), floatKI11);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI83.getKey(), floatKI83);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI51.getKey(), floatKI51);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI71.getKey(), floatKI71);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI21.getKey(), floatKI21);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI81.getKey(), floatKI81);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI92.getKey(), floatKI92);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI91.getKey(), floatKI91);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI01.getKey(), floatKI01);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI82.getKey(), floatKI82);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI61.getKey(), floatKI61);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI41.getKey(), floatKI41);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI31.getKey(), floatKI31);
+ basicModel.getKeyInformation().getKeyInfoMap().put(floatKI93.getKey(), floatKI93);
+
+ return basicModel;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/basicmodel/service/ModelServiceTest.java b/model/src/test/java/org/onap/policy/apex/model/basicmodel/service/ModelServiceTest.java
new file mode 100644
index 000000000..746e10607
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/basicmodel/service/ModelServiceTest.java
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.basicmodel.service;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.handling.DummyApexBasicModelCreator;
+
+public class ModelServiceTest {
+
+ @Test
+ public void testModelService() {
+ ModelService.clear();
+
+ assertFalse(ModelService.existsModel(AxKeyInformation.class));
+ assertThatThrownBy(() -> ModelService.getModel(AxKeyInformation.class))
+ .hasMessage("Model for org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation "
+ + "not found in model service");
+ ModelService.registerModel(AxKeyInformation.class,
+ new DummyApexBasicModelCreator().getModel().getKeyInformation());
+ assertTrue(ModelService.existsModel(AxKeyInformation.class));
+ assertNotNull(ModelService.getModel(AxKeyInformation.class));
+
+ ModelService.deregisterModel(AxKeyInformation.class);
+
+ assertFalse(ModelService.existsModel(AxKeyInformation.class));
+ assertThatThrownBy(() -> ModelService.getModel(AxKeyInformation.class))
+ .hasMessage("Model for org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation "
+ + "not found in model service");
+ ModelService.registerModel(AxKeyInformation.class,
+ new DummyApexBasicModelCreator().getModel().getKeyInformation());
+ assertTrue(ModelService.existsModel(AxKeyInformation.class));
+ assertNotNull(ModelService.getModel(AxKeyInformation.class));
+
+ ModelService.clear();
+ assertFalse(ModelService.existsModel(AxKeyInformation.class));
+ assertThatThrownBy(() -> ModelService.getModel(AxKeyInformation.class))
+ .hasMessage("Model for org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation "
+ + "not found in model service");
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextAlbumsTest.java b/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextAlbumsTest.java
new file mode 100644
index 000000000..44161b329
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextAlbumsTest.java
@@ -0,0 +1,248 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Context album tests.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextAlbumsTest {
+
+ @Test
+ public void testNewAxContectAlbum() {
+ assertNotNull(new AxContextAlbum());
+ assertNotNull(new AxContextAlbum(new AxArtifactKey()));
+ assertNotNull(new AxContextAlbum(new AxArtifactKey(), "AlbumScope", false, new AxArtifactKey()));
+ }
+
+ @Test
+ public void testContextAlbums() {
+ final AxArtifactKey albumKey = new AxArtifactKey("AlbumName", "0.0.1");
+ final AxArtifactKey albumSchemaKey = new AxArtifactKey("AlbumSchemaName", "0.0.1");
+
+ final AxContextAlbum album = new AxContextAlbum(albumKey, "AlbumScope", false, albumSchemaKey);
+ assertNotNull(album);
+
+ final AxArtifactKey newKey = new AxArtifactKey("NewAlbumName", "0.0.1");
+ album.setKey(newKey);
+ assertEquals("NewAlbumName:0.0.1", album.getKey().getId());
+ assertEquals("NewAlbumName:0.0.1", album.getKeys().get(0).getId());
+ album.setKey(albumKey);
+
+ assertThatThrownBy(() -> album.setScope(""))
+ .hasMessage("parameter \"scope\": value \"\", does not match regular expression "
+ + "\"[A-Za-z0-9\\-_]+\"");
+
+ album.setScope("NewAlbumScope");
+ assertEquals("NewAlbumScope", album.getScope());
+
+ assertEquals(false, album.isWritable());
+ album.setWritable(true);
+ assertEquals(true, album.isWritable());
+
+ final AxArtifactKey newSchemaKey = new AxArtifactKey("NewAlbumSchemaName", "0.0.1");
+ album.setItemSchema(newSchemaKey);
+ assertEquals("NewAlbumSchemaName:0.0.1", album.getItemSchema().getId());
+ album.setItemSchema(albumSchemaKey);
+ }
+
+ private AxContextAlbum setTestAlbum() {
+ final AxArtifactKey newKey = new AxArtifactKey("NewAlbumName", "0.0.1");
+ final AxArtifactKey newSchemaKey = new AxArtifactKey("NewAlbumSchemaName", "0.0.1");
+
+ final AxContextAlbum album = new AxContextAlbum(newKey, "AlbumScope", false, newSchemaKey);
+
+ album.setScope("NewAlbumScope");
+ album.setWritable(true);
+
+ return album;
+ }
+
+ @Test
+ public void testAxvalidationAlbum() {
+ final AxContextAlbum album = setTestAlbum();
+ AxValidationResult result = new AxValidationResult();
+ result = album.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ album.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = album.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ final AxArtifactKey newKey = new AxArtifactKey("NewAlbumName", "0.0.1");
+ album.setKey(newKey);
+ result = new AxValidationResult();
+ result = album.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ album.setScope("UNDEFINED");
+ result = new AxValidationResult();
+ result = album.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ album.setScope("NewAlbumScope");
+ result = new AxValidationResult();
+ result = album.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ album.setItemSchema(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = album.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ final AxArtifactKey albumSchemaKey = new AxArtifactKey("AlbumSchemaName", "0.0.1");
+ album.setItemSchema(albumSchemaKey);
+ result = new AxValidationResult();
+ result = album.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ }
+
+ @Test
+ public void testEqualsAlbum() {
+ final AxContextAlbum album = setTestAlbum();
+ final AxArtifactKey newKey = new AxArtifactKey("NewAlbumName", "0.0.1");
+ final AxArtifactKey albumSchemaKey = new AxArtifactKey("AlbumSchemaName", "0.0.1");
+ album.setItemSchema(albumSchemaKey);
+
+ final AxContextAlbum clonedAlbum = new AxContextAlbum(album);
+ assertEquals("AxContextAlbum(key=AxArtifactKey:(name=NewAlbumName,version=0.0.1), "
+ + "scope=NewAlbumScope, isWritable=true, itemSchema="
+ + "AxArtifactKey:(name=AlbumSchemaName,version=0.0.1))", clonedAlbum.toString());
+
+ assertNotEquals(0, album.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(album, album); // NOSONAR
+ assertEquals(album, clonedAlbum);
+ assertNotNull(album);
+ assertNotEquals(album, (Object) "Hello");
+ assertNotEquals(album, new AxContextAlbum(new AxArtifactKey(), "Scope", false, AxArtifactKey.getNullKey()));
+ assertNotEquals(album, new AxContextAlbum(newKey, "Scope", false, AxArtifactKey.getNullKey()));
+ assertNotEquals(album, new AxContextAlbum(newKey, "NewAlbumScope", false, AxArtifactKey.getNullKey()));
+ assertNotEquals(album, new AxContextAlbum(newKey, "NewAlbumScope", true, AxArtifactKey.getNullKey()));
+ assertEquals(album, new AxContextAlbum(newKey, "NewAlbumScope", true, albumSchemaKey));
+
+ assertEquals(0, album.compareTo(album));
+ assertEquals(0, album.compareTo(clonedAlbum));
+ assertNotEquals(0, album.compareTo(null));
+ assertNotEquals(0, album.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, album.compareTo(
+ new AxContextAlbum(new AxArtifactKey(), "Scope", false, AxArtifactKey.getNullKey())));
+ assertNotEquals(0, album.compareTo(new AxContextAlbum(newKey, "Scope", false, AxArtifactKey.getNullKey())));
+ assertNotEquals(0, album
+ .compareTo(new AxContextAlbum(newKey, "NewAlbumScope", false, AxArtifactKey.getNullKey())));
+ assertNotEquals(0,
+ album.compareTo(new AxContextAlbum(newKey, "NewAlbumScope", true, AxArtifactKey.getNullKey())));
+ assertEquals(0, album.compareTo(new AxContextAlbum(newKey, "NewAlbumScope", true, albumSchemaKey)));
+ }
+
+ @Test
+ public void testMultipleAlbums() {
+ final AxContextAlbums albums = new AxContextAlbums();
+ final AxContextAlbum album = setTestAlbum();
+ final AxArtifactKey newKey = new AxArtifactKey("NewAlbumName", "0.0.1");
+ AxValidationResult result = new AxValidationResult();
+ result = albums.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ // Observation, no albums in album map
+ albums.setKey(new AxArtifactKey("AlbumsKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = albums.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ albums.getAlbumsMap().put(newKey, album);
+ result = new AxValidationResult();
+ result = albums.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ albums.getAlbumsMap().put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = albums.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ albums.getAlbumsMap().remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = albums.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ albums.getAlbumsMap().put(new AxArtifactKey("NullValueKey", "0.0.1"), null);
+ result = new AxValidationResult();
+ result = albums.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ albums.getAlbumsMap().remove(new AxArtifactKey("NullValueKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = albums.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ }
+
+ @Test
+ public void testClonedAlbums() {
+ final AxContextAlbums albums = new AxContextAlbums();
+ final AxContextAlbum album = setTestAlbum();
+ final AxArtifactKey newKey = new AxArtifactKey("NewAlbumName", "0.0.1");
+ albums.setKey(new AxArtifactKey("AlbumsKey", "0.0.1"));
+ albums.getAlbumsMap().put(newKey, album);
+ albums.clean();
+
+ final AxContextAlbums clonedAlbums = new AxContextAlbums(albums);
+ assertThat(clonedAlbums.toString()).startsWith(
+ "AxContextAlbums(key=AxArtifactKey:(name=AlbumsKey,version=0.0.1)");
+
+ assertNotEquals(0, albums.hashCode());
+
+ assertEquals(albums, clonedAlbums);
+ assertNotNull(albums);
+ assertNotEquals(albums, (Object) "Hello");
+ assertNotEquals(albums, new AxContextAlbums(new AxArtifactKey()));
+
+ assertEquals(0, albums.compareTo(albums));
+ assertEquals(0, albums.compareTo(clonedAlbums));
+ assertNotEquals(0, albums.compareTo(null));
+ assertNotEquals(0, albums.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, albums.compareTo(new AxContextAlbums(new AxArtifactKey())));
+
+ clonedAlbums.get(newKey).setScope("YetAnotherScope");
+ assertNotEquals(0, albums.compareTo(clonedAlbums));
+
+ assertEquals("NewAlbumName", albums.get("NewAlbumName").getKey().getName());
+ assertEquals("NewAlbumName", albums.get("NewAlbumName", "0.0.1").getKey().getName());
+ assertEquals(1, albums.getAll("NewAlbumName", "0.0.1").size());
+ assertEquals(0, albums.getAll("NonExistantAlbumName").size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextModelTest.java b/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextModelTest.java
new file mode 100644
index 000000000..b148ef6be
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextModelTest.java
@@ -0,0 +1,95 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+
+/**
+ * Context model tests.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextModelTest {
+
+ @Test
+ public void test() {
+ assertNotNull(new AxContextModel());
+ assertNotNull(new AxContextModel(new AxArtifactKey()));
+ assertNotNull(new AxContextModel(new AxArtifactKey(), new AxContextSchemas(), new AxKeyInformation()));
+ assertNotNull(new AxContextModel(new AxArtifactKey(), new AxContextSchemas(), new AxContextAlbums(),
+ new AxKeyInformation()));
+
+ final AxArtifactKey modelKey = new AxArtifactKey("ModelKey", "0.0.1");
+ final AxArtifactKey schemasKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxArtifactKey albumsKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxArtifactKey keyInfoKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxContextModel model = new AxContextModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxContextAlbums(albumsKey), new AxKeyInformation(keyInfoKey));
+ model.register();
+
+ model.clean();
+ assertNotNull(model);
+ assertThat(model.toString()).startsWith("AxContextModel(super=AxContextModel:(key=AxArtifactKey:");
+
+ final AxContextModel clonedModel = new AxContextModel(model);
+
+ assertNotEquals(0, model.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(model, model); // NOSONAR
+ assertEquals(model, clonedModel);
+ assertNotEquals(model, (Object) "Hello");
+ assertNotEquals(model, new AxContextModel(new AxArtifactKey()));
+ assertNotEquals(model, new AxContextModel(new AxArtifactKey(), new AxContextSchemas(), new AxContextAlbums(),
+ new AxKeyInformation()));
+ assertNotEquals(model, new AxContextModel(modelKey, new AxContextSchemas(), new AxContextAlbums(),
+ new AxKeyInformation()));
+ assertNotEquals(model, new AxContextModel(modelKey, new AxContextSchemas(), new AxContextAlbums(),
+ new AxKeyInformation(keyInfoKey)));
+ assertNotEquals(model, new AxContextModel(modelKey, new AxContextSchemas(schemasKey), new AxContextAlbums(),
+ new AxKeyInformation(keyInfoKey)));
+ assertEquals(model, new AxContextModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxContextAlbums(albumsKey), new AxKeyInformation(keyInfoKey)));
+
+ assertEquals(0, model.compareTo(model));
+ assertEquals(0, model.compareTo(clonedModel));
+ assertNotEquals(0, model.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, model.compareTo(new AxContextModel(new AxArtifactKey(), new AxContextSchemas(),
+ new AxContextAlbums(), new AxKeyInformation())));
+ assertNotEquals(0, model.compareTo(new AxContextModel(modelKey, new AxContextSchemas(), new AxContextAlbums(),
+ new AxKeyInformation())));
+ assertNotEquals(0, model.compareTo(new AxContextModel(modelKey, new AxContextSchemas(), new AxContextAlbums(),
+ new AxKeyInformation(keyInfoKey))));
+ assertNotEquals(0, model.compareTo(new AxContextModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxContextAlbums(), new AxKeyInformation(keyInfoKey))));
+ assertEquals(0, model.compareTo(new AxContextModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxContextAlbums(albumsKey), new AxKeyInformation(keyInfoKey))));
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextSchemasTest.java b/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextSchemasTest.java
new file mode 100644
index 000000000..52cca14bf
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/contextmodel/concepts/ContextSchemasTest.java
@@ -0,0 +1,229 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020-2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Context schema tests.
+ */
+public class ContextSchemasTest {
+
+ @Test
+ public void testNewAxContextSchema() {
+ assertNotNull(new AxContextSchema());
+ assertNotNull(new AxContextSchema(new AxArtifactKey(), "SchemaFlavour", "SchemaDefinition"));
+
+ }
+
+ @Test
+ public void testContextSchemas() {
+ final AxContextSchema schema = new AxContextSchema(new AxArtifactKey("SchemaName", "0.0.1"), "SchemaFlavour",
+ "SchemaDefinition");
+ assertNotNull(schema);
+
+ final AxArtifactKey newKey = new AxArtifactKey("NewSchemaName", "0.0.1");
+ schema.setKey(newKey);
+ assertEquals("NewSchemaName:0.0.1", schema.getKey().getId());
+ assertEquals("NewSchemaName:0.0.1", schema.getKeys().get(0).getId());
+
+ assertThatThrownBy(() -> schema.setSchemaFlavour(""))
+ .hasMessage("parameter \"schemaFlavour\": value \"\", "
+ + "does not match regular expression \"[A-Za-z0-9\\-_]+\"");
+ schema.setSchemaFlavour("NewSchemaFlavour");
+ assertEquals("NewSchemaFlavour", schema.getSchemaFlavour());
+
+ schema.setSchema("NewSchemaDefinition");
+ assertEquals("NewSchemaDefinition", schema.getSchema());
+ }
+
+ private AxContextSchema setTestSchema() {
+ final AxContextSchema schema = new AxContextSchema(new AxArtifactKey("SchemaName", "0.0.1"), "SchemaFlavour",
+ "SchemaDefinition");
+ final AxArtifactKey newKey = new AxArtifactKey("NewSchemaName", "0.0.1");
+ schema.setKey(newKey);
+ schema.setSchemaFlavour("NewSchemaFlavour");
+ schema.setSchema("NewSchemaDefinition");
+
+ return schema;
+ }
+
+ @Test
+ public void testAxvalidationSchema() {
+ AxContextSchema schema = setTestSchema();
+ AxValidationResult result = new AxValidationResult();
+ result = schema.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ schema.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = schema.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ final AxArtifactKey newKey = new AxArtifactKey("NewSchemaName", "0.0.1");
+ schema.setKey(newKey);
+ result = new AxValidationResult();
+ result = schema.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ schema.setSchemaFlavour("UNDEFINED");
+ result = new AxValidationResult();
+ result = schema.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ schema.setSchemaFlavour("NewSchemaFlavour");
+ result = new AxValidationResult();
+ result = schema.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ schema.setSchema("");
+ result = new AxValidationResult();
+ result = schema.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ schema.setSchema("NewSchemaDefinition");
+ result = new AxValidationResult();
+ result = schema.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+ }
+
+ @Test
+ public void testEqualsSchema() {
+ AxContextSchema schema = setTestSchema();
+ schema.clean();
+
+ final AxContextSchema clonedSchema = new AxContextSchema(schema);
+ assertEquals("AxContextSchema(key=AxArtifactKey:(name=NewSchemaName,version=0.0.1), "
+ + "schemaFlavour=NewSchemaFlavour, schemaDefinition=NewSchemaDefinition)",
+ clonedSchema.toString());
+
+ assertNotEquals(0, schema.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(schema, schema); // NOSONAR
+ assertEquals(schema, clonedSchema);
+ assertNotNull(schema);
+ assertNotEquals(schema, (Object) "Hello");
+ assertNotEquals(schema, new AxContextSchema(new AxArtifactKey(), "Flavour", "Def"));
+
+ final AxArtifactKey newKey = new AxArtifactKey("NewSchemaName", "0.0.1");
+ assertNotEquals(schema, new AxContextSchema(newKey, "Flavour", "Def"));
+ assertNotEquals(schema, new AxContextSchema(newKey, "NewSchemaFlavour", "Def"));
+ assertEquals(schema, new AxContextSchema(newKey, "NewSchemaFlavour", "NewSchemaDefinition"));
+
+ assertEquals(0, schema.compareTo(schema));
+ assertEquals(0, schema.compareTo(clonedSchema));
+ assertNotEquals(0, schema.compareTo(null));
+ assertNotEquals(0, schema.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, schema.compareTo(new AxContextSchema(new AxArtifactKey(), "Flavour", "Def")));
+ assertNotEquals(0, schema.compareTo(new AxContextSchema(newKey, "Flavour", "Def")));
+ assertNotEquals(0, schema.compareTo(new AxContextSchema(newKey, "NewSchemaFlavour", "Def")));
+ assertEquals(0, schema.compareTo(new AxContextSchema(newKey, "NewSchemaFlavour", "NewSchemaDefinition")));
+ }
+
+ @Test
+ public void testMultipleSchemas() {
+ final AxContextSchemas schemas = new AxContextSchemas();
+ AxValidationResult result = new AxValidationResult();
+ result = schemas.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ // Still invalid, no schemas in schema map
+ schemas.setKey(new AxArtifactKey("SchemasKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = schemas.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ AxContextSchema schema = setTestSchema();
+ final AxArtifactKey newKey = new AxArtifactKey("NewSchemaName", "0.0.1");
+ schemas.getSchemasMap().put(newKey, schema);
+ result = new AxValidationResult();
+ result = schemas.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ schemas.getSchemasMap().put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = schemas.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ schemas.getSchemasMap().remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = schemas.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ schemas.getSchemasMap().put(new AxArtifactKey("NullValueKey", "0.0.1"), null);
+ result = new AxValidationResult();
+ result = schemas.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ schemas.getSchemasMap().remove(new AxArtifactKey("NullValueKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = schemas.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ }
+
+ @Test
+ public void testClonedSchemas() {
+ final AxContextSchemas schemas = new AxContextSchemas();
+ AxContextSchema schema = setTestSchema();
+ final AxArtifactKey newKey = new AxArtifactKey("NewSchemaName", "0.0.1");
+ schemas.setKey(new AxArtifactKey("SchemasKey", "0.0.1"));
+ schemas.getSchemasMap().put(newKey, schema);
+ schemas.clean();
+
+ final AxContextSchemas clonedSchemas = new AxContextSchemas(schemas);
+ assertThat(clonedSchemas.toString())
+ .startsWith("AxContextSchemas(key=AxArtifactKey:(name=SchemasKey,version=0.0.1),");
+
+ assertNotEquals(0, schemas.hashCode());
+
+ assertEquals(schemas, clonedSchemas);
+ assertNotNull(schemas);
+ assertNotEquals(schemas, (Object) "Hello");
+ assertNotEquals(schemas, new AxContextSchemas(new AxArtifactKey()));
+
+ assertEquals(0, schemas.compareTo(schemas));
+ assertEquals(0, schemas.compareTo(clonedSchemas));
+ assertNotEquals(0, schemas.compareTo(null));
+ assertNotEquals(0, schemas.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, schemas.compareTo(new AxContextSchemas(new AxArtifactKey())));
+
+ clonedSchemas.get(newKey).setSchemaFlavour("YetAnotherFlavour");
+ assertNotEquals(0, schemas.compareTo(clonedSchemas));
+
+ assertEquals("NewSchemaName", schemas.get("NewSchemaName").getKey().getName());
+ assertEquals("NewSchemaName", schemas.get("NewSchemaName", "0.0.1").getKey().getName());
+ assertEquals(1, schemas.getAll("NewSchemaName", "0.0.1").size());
+ assertEquals(0, schemas.getAll("NonExistantSchemaName").size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/ApexContextModelTest.java b/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/ApexContextModelTest.java
new file mode 100644
index 000000000..998469bac
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/ApexContextModelTest.java
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.contextmodel.handling;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+
+/**
+ * Apex context model tests.
+ *
+ * @author liam
+ *
+ */
+public class ApexContextModelTest {
+
+ private static final String VALID_MODEL_STRING = "***validation of model successful***";
+
+ private static final String OBSERVATION_MODEL_STRING = "\n"
+ + "***observations noted during validation of model***\n"
+ + "AxArtifactKey:(name=contextAlbum1,version=0.0.1):"
+ + "org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo:OBSERVATION:description is blank\n"
+ + "********************************";
+
+ private static final String WARNING_MODEL_STRING = "\n" + "***warnings issued during validation of model***\n"
+ + "AxArtifactKey:(name=contextAlbum1,version=0.0.1):"
+ + "org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo:WARNING:"
+ + "UUID is a zero UUID: 00000000-0000-0000-0000-000000000000\n"
+ + "********************************";
+
+ private static final String INVALID_MODEL_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=StringType,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema:INVALID:"
+ + "no schemaDefinition specified, schemaDefinition may not be blank\n"
+ + "AxArtifactKey:(name=contextAlbum0,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum:INVALID:"
+ + "scope is not defined\n" + "********************************";
+
+ private static final String INVALID_MODEL_MALSTRUCTURED_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=ContextModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=contextAlbum1,version=0.0.2)\n"
+ + "AxArtifactKey:(name=contextAlbum1,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextModel:WARNING:"
+ + "key not found for key information entry\n" + "AxArtifactKey:(name=ContextSchemas,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas:INVALID:"
+ + "key on schemas entry AxArtifactKey:(name=MapType,version=0.0.1) "
+ + "does not equal entry key AxArtifactKey:(name=MapType,version=0.0.2)\n"
+ + "AxArtifactKey:(name=contextAlbums,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums:INVALID:"
+ + "key on context album entry key AxArtifactKey:(name=contextAlbum1,version=0.0.1) "
+ + "does not equal context album value key AxArtifactKey:(name=contextAlbum1,version=0.0.2)\n"
+ + "********************************";
+
+ TestApexModel<AxContextModel> testApexModel;
+
+ /**
+ * Set up tests.
+ *
+ * @throws Exception a testing exception
+ */
+ @Before
+ public void setup() throws Exception {
+ testApexModel = new TestApexModel<AxContextModel>(AxContextModel.class, new TestApexContextModelCreator());
+ }
+
+ @Test
+ public void testModelValid() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelValid();
+ assertEquals(VALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testApexModelVaidateObservation() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateObservation();
+ assertEquals(OBSERVATION_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testApexModelVaidateWarning() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateWarning();
+ assertEquals(WARNING_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateInvalidModel() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateInvalidModel();
+ assertEquals(INVALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateMalstructured() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateMalstructured();
+ assertEquals(INVALID_MODEL_MALSTRUCTURED_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelWriteReadJson() throws Exception {
+ testApexModel.testApexModelWriteReadJson();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/ContextComparisonTest.java b/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/ContextComparisonTest.java
new file mode 100644
index 000000000..483bc3661
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/ContextComparisonTest.java
@@ -0,0 +1,189 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.contextmodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference;
+
+/**
+ * Test context comparisons.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextComparisonTest {
+ private AxContextModel emptyModel;
+ private AxContextModel fullModel;
+ private AxContextModel noGlobalContextModel;
+ private AxContextModel shellModel;
+ private AxContextModel singleEntryModel;
+
+ /**
+ * Set up tests.
+ */
+ @Before
+ public void getContext() {
+ final TestContextComparisonFactory factory = new TestContextComparisonFactory();
+ emptyModel = factory.getEmptyModel();
+ fullModel = factory.getFullModel();
+ noGlobalContextModel = factory.getNoGlobalContextModel();
+ shellModel = factory.getShellModel();
+ singleEntryModel = factory.getSingleEntryModel();
+ }
+
+ @Test
+ public void testEmptyEmpty() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(emptyModel.getSchemas(), emptyModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(emptyModel.getSchemas().getSchemasMap(), schemaResult.getIdenticalValues());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(emptyModel.getAlbums(), emptyModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(emptyModel.getAlbums().getAlbumsMap(), albumResult.getIdenticalValues());
+ }
+
+ @Test
+ public void testEmptyFull() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(emptyModel.getSchemas(), fullModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(fullModel.getSchemas().getSchemasMap(), schemaResult.getRightOnly());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(emptyModel.getAlbums(), fullModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(fullModel.getAlbums().getAlbumsMap(), albumResult.getRightOnly());
+ }
+
+ @Test
+ public void testFullEmpty() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(fullModel.getSchemas(), emptyModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(fullModel.getSchemas().getSchemasMap(), schemaResult.getLeftOnly());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(fullModel.getAlbums(), emptyModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(fullModel.getAlbums().getAlbumsMap(), albumResult.getLeftOnly());
+ }
+
+ @Test
+ public void testEmptyNoGlobalContext() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(emptyModel.getSchemas(), noGlobalContextModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(noGlobalContextModel.getSchemas().getSchemasMap(), schemaResult.getRightOnly());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(emptyModel.getAlbums(), noGlobalContextModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(noGlobalContextModel.getAlbums().getAlbumsMap(), albumResult.getRightOnly());
+ }
+
+ @Test
+ public void testNoGlobalContextEmpty() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(noGlobalContextModel.getSchemas(), emptyModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(noGlobalContextModel.getSchemas().getSchemasMap(), schemaResult.getLeftOnly());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(noGlobalContextModel.getAlbums(), emptyModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(noGlobalContextModel.getAlbums().getAlbumsMap(), albumResult.getLeftOnly());
+ }
+
+ @Test
+ public void testEmptyShell() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(emptyModel.getSchemas(), shellModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(shellModel.getSchemas().getSchemasMap(), schemaResult.getRightOnly());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(emptyModel.getAlbums(), shellModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(shellModel.getAlbums().getAlbumsMap(), albumResult.getRightOnly());
+ }
+
+ @Test
+ public void testShellEmpty() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(shellModel.getSchemas(), emptyModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(shellModel.getSchemas().getSchemasMap(), schemaResult.getLeftOnly());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(shellModel.getAlbums(), emptyModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(shellModel.getAlbums().getAlbumsMap(), albumResult.getLeftOnly());
+ }
+
+ @Test
+ public void testEmptySingleEntry() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(emptyModel.getSchemas(), singleEntryModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(singleEntryModel.getSchemas().getSchemasMap(), schemaResult.getRightOnly());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(emptyModel.getAlbums(), singleEntryModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(singleEntryModel.getAlbums().getAlbumsMap(), albumResult.getRightOnly());
+ }
+
+ @Test
+ public void testSingleEntryEmpty() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(singleEntryModel.getSchemas(), emptyModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(singleEntryModel.getSchemas().getSchemasMap(), schemaResult.getLeftOnly());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(singleEntryModel.getAlbums(), emptyModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(singleEntryModel.getAlbums().getAlbumsMap(), albumResult.getLeftOnly());
+ }
+
+ @Test
+ public void testFullFull() {
+ final KeyedMapDifference<AxArtifactKey, AxContextSchema> schemaResult = new ContextComparer()
+ .compare(fullModel.getSchemas(), fullModel.getSchemas());
+ assertNotNull(schemaResult);
+ assertEquals(fullModel.getSchemas().getSchemasMap(), schemaResult.getIdenticalValues());
+
+ final KeyedMapDifference<AxArtifactKey, AxContextAlbum> albumResult = new ContextComparer()
+ .compare(fullModel.getAlbums(), fullModel.getAlbums());
+ assertNotNull(albumResult);
+ assertEquals(fullModel.getAlbums().getAlbumsMap(), albumResult.getIdenticalValues());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/TestApexContextModelCreator.java b/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/TestApexContextModelCreator.java
new file mode 100644
index 000000000..3fe7e3aa2
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/TestApexContextModelCreator.java
@@ -0,0 +1,122 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.handling;
+
+import java.util.UUID;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+
+public class TestApexContextModelCreator implements TestApexModelCreator<AxContextModel> {
+
+ @Override
+ public AxContextModel getModel() {
+ final AxContextSchema schema0 = new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java",
+ "org.onap.policy.apex.concept.TestContextItem000");
+ final AxContextSchema schema1 = new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java",
+ "org.onap.policy.apex.concept.TestContextItem00A");
+
+ final AxContextSchemas contextSchemas = new AxContextSchemas(new AxArtifactKey("ContextSchemas", "0.0.1"));
+ contextSchemas.getSchemasMap().put(schema0.getKey(), schema0);
+ contextSchemas.getSchemasMap().put(schema1.getKey(), schema1);
+
+ final AxContextAlbum contextAlbum0 =
+ new AxContextAlbum(new AxArtifactKey("contextAlbum0", "0.0.1"), "APPLICATION", true, schema0.getKey());
+ final AxContextAlbum contextAlbum1 =
+ new AxContextAlbum(new AxArtifactKey("contextAlbum1", "0.0.1"), "GLOBAL", false, schema1.getKey());
+
+ final AxContextAlbums axContext = new AxContextAlbums(new AxArtifactKey("contextAlbums", "0.0.1"));
+ axContext.getAlbumsMap().put(contextAlbum0.getKey(), contextAlbum0);
+ axContext.getAlbumsMap().put(contextAlbum1.getKey(), contextAlbum1);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1"));
+ final AxContextModel contextModel = new AxContextModel(new AxArtifactKey("ContextModel", "0.0.1"),
+ contextSchemas, axContext, keyInformation);
+
+ contextModel.setKeyInformation(keyInformation);
+ contextModel.getKeyInformation().getKeyInfoMap().put(schema0.getKey(), new AxKeyInfo(schema0.getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000001"), "axContextSchema0"));
+ contextModel.getKeyInformation().getKeyInfoMap().put(schema1.getKey(), new AxKeyInfo(schema1.getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000002"), "axContextSchema1"));
+ contextModel.getKeyInformation().getKeyInfoMap().put(contextSchemas.getKey(), new AxKeyInfo(
+ contextSchemas.getKey(), UUID.fromString("00000000-0000-0000-0000-000000000003"), "ContextSchemas"));
+ contextModel.getKeyInformation().getKeyInfoMap().put(contextAlbum0.getKey(), new AxKeyInfo(
+ contextAlbum0.getKey(), UUID.fromString("00000000-0000-0000-0000-000000000004"), "contextAlbum0"));
+ contextModel.getKeyInformation().getKeyInfoMap().put(contextAlbum1.getKey(), new AxKeyInfo(
+ contextAlbum1.getKey(), UUID.fromString("00000000-0000-0000-0000-000000000005"), "contextAlbum1"));
+ contextModel.getKeyInformation().getKeyInfoMap().put(axContext.getKey(), new AxKeyInfo(axContext.getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000006"), "axContext"));
+ contextModel.getKeyInformation().getKeyInfoMap().put(contextModel.getKey(), new AxKeyInfo(contextModel.getKey(),
+ UUID.fromString("00000000-0000-0000-0000-000000000007"), "contextModel"));
+ contextModel.getKeyInformation().getKeyInfoMap().put(keyInformation.getKey(), new AxKeyInfo(
+ keyInformation.getKey(), UUID.fromString("00000000-0000-0000-0000-000000000008"), "keyInformation"));
+
+ return contextModel;
+ }
+
+ @Override
+ public AxContextModel getInvalidModel() {
+ final AxContextModel contextModel = getModel();
+
+ contextModel.getAlbums().get(new AxArtifactKey("contextAlbum0", "0.0.1")).setScope("UNDEFINED");
+
+ contextModel.getSchemas().get(new AxArtifactKey("StringType", "0.0.1")).setSchema("");
+
+ return contextModel;
+ }
+
+ @Override
+ public AxContextModel getMalstructuredModel() {
+ final AxContextModel contextModel = getModel();
+
+ contextModel.getAlbums().get(new AxArtifactKey("contextAlbum1", "0.0.1"))
+ .setKey(new AxArtifactKey("contextAlbum1", "0.0.2"));;
+ contextModel.getSchemas().get(new AxArtifactKey("MapType", "0.0.1"))
+ .setKey(new AxArtifactKey("MapType", "0.0.2"));;
+
+ return contextModel;
+ }
+
+ @Override
+ public AxContextModel getObservationModel() {
+ final AxContextModel contextModel = getModel();
+
+ contextModel.getKeyInformation().get("contextAlbum1", "0.0.1").setDescription("");
+
+ return contextModel;
+ }
+
+ @Override
+ public AxContextModel getWarningModel() {
+ final AxContextModel contextModel = getModel();
+
+ contextModel.getKeyInformation().get("contextAlbum1", "0.0.1")
+ .setUuid(UUID.fromString("00000000-0000-0000-0000-000000000000"));
+
+ return contextModel;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/TestContextComparisonFactory.java b/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/TestContextComparisonFactory.java
new file mode 100644
index 000000000..f7c7a1345
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/contextmodel/handling/TestContextComparisonFactory.java
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.contextmodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+
+/**
+ * This class creates sample Policy Models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestContextComparisonFactory {
+
+ /**
+ * Get a full context model.
+ * @return the model
+ */
+ public AxContextModel getFullModel() {
+ final AxContextSchema testContextSchema000 =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema000", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema000");
+ final AxContextSchema testContextSchema00A =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema00A", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema00A");
+ final AxContextSchema testContextSchema00C =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema00C", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema00C");
+
+ final AxContextAlbum externalContextAlbum = new AxContextAlbum(
+ new AxArtifactKey("ExternalContextAlbum", "0.0.1"), "EXTERNAL", false, testContextSchema000.getKey());
+ final AxContextAlbum globalContextAlbum = new AxContextAlbum(new AxArtifactKey("GlobalContextAlbum", "0.0.1"),
+ "GLOBAL", true, testContextSchema00A.getKey());
+ final AxContextAlbum policy0ContextAlbum = new AxContextAlbum(new AxArtifactKey("Policy0ContextAlbum", "0.0.1"),
+ "APPLICATION", true, testContextSchema00C.getKey());
+ final AxContextAlbum policy1ContextAlbum = new AxContextAlbum(
+ new AxArtifactKey("Policy1ContextAlbum ", "0.0.1"), "APPLICATION", true, testContextSchema00C.getKey());
+
+ final AxContextModel contextModel = new AxContextModel(new AxArtifactKey("ContextModel", "0.0.1"));
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema000.getKey(), testContextSchema000);
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema00A.getKey(), testContextSchema00A);
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema00C.getKey(), testContextSchema00C);
+
+ contextModel.getAlbums().getAlbumsMap().put(externalContextAlbum.getKey(), externalContextAlbum);
+ contextModel.getAlbums().getAlbumsMap().put(globalContextAlbum.getKey(), globalContextAlbum);
+ contextModel.getAlbums().getAlbumsMap().put(policy0ContextAlbum.getKey(), policy0ContextAlbum);
+ contextModel.getAlbums().getAlbumsMap().put(policy1ContextAlbum.getKey(), policy1ContextAlbum);
+
+ return contextModel;
+ }
+
+ public AxContextModel getEmptyModel() {
+ return new AxContextModel(new AxArtifactKey("Context", "0.0.1"));
+ }
+
+ /**
+ * Get a skeleton model.
+ * @return The model
+ */
+ public AxContextModel getShellModel() {
+ final AxContextSchema testContextSchema000 =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema000", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema000");
+ final AxContextSchema testContextSchema00A =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema00A", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema00A");
+ final AxContextSchema testContextSchema00C =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema00C", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema00C");
+
+ final AxContextModel contextModel = new AxContextModel(new AxArtifactKey("ContextModel", "0.0.1"));
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema000.getKey(), testContextSchema000);
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema00A.getKey(), testContextSchema00A);
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema00C.getKey(), testContextSchema00C);
+
+ return contextModel;
+ }
+
+ /**
+ * Get a single entry model.
+ * @return The single entry model
+ */
+ public AxContextModel getSingleEntryModel() {
+ final AxContextSchema testContextSchema000 =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema000", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema000");
+
+ final AxContextAlbum policy1ContextAlbum = new AxContextAlbum(
+ new AxArtifactKey("Policy1ContextAlbum ", "0.0.1"), "APPLICATION", true, testContextSchema000.getKey());
+
+ final AxContextModel contextModel = new AxContextModel(new AxArtifactKey("ContextModel", "0.0.1"));
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema000.getKey(), testContextSchema000);
+
+ contextModel.getAlbums().getAlbumsMap().put(policy1ContextAlbum.getKey(), policy1ContextAlbum);
+
+ return contextModel;
+ }
+
+ /**
+ * Get a model with no global entries.
+ * @return the model
+ */
+ public AxContextModel getNoGlobalContextModel() {
+ final AxContextSchema testContextSchema000 =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema000", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema000");
+ final AxContextSchema testContextSchema00C =
+ new AxContextSchema(new AxArtifactKey("TestContextSchema00C", "0.0.1"), "JAVA",
+ "org.onap.policy.apex.concept.TestContextSchema00C");
+
+ final AxContextAlbum externalContextAlbum = new AxContextAlbum(
+ new AxArtifactKey("ExternalContextAlbum", "0.0.1"), "EXTERNAL", false, testContextSchema000.getKey());
+ final AxContextAlbum policy0ContextAlbum = new AxContextAlbum(new AxArtifactKey("Policy0ContextAlbum", "0.0.1"),
+ "APPLICATION", true, testContextSchema00C.getKey());
+ final AxContextAlbum policy1ContextAlbum = new AxContextAlbum(
+ new AxArtifactKey("Policy1ContextAlbum ", "0.0.1"), "APPLICATION", true, testContextSchema00C.getKey());
+
+ final AxContextModel contextModel = new AxContextModel(new AxArtifactKey("ContextModel", "0.0.1"));
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema000.getKey(), testContextSchema000);
+ contextModel.getSchemas().getSchemasMap().put(testContextSchema00C.getKey(), testContextSchema00C);
+
+ contextModel.getAlbums().getAlbumsMap().put(externalContextAlbum.getKey(), externalContextAlbum);
+ contextModel.getAlbums().getAlbumsMap().put(policy0ContextAlbum.getKey(), policy0ContextAlbum);
+ contextModel.getAlbums().getAlbumsMap().put(policy1ContextAlbum.getKey(), policy1ContextAlbum);
+
+ return contextModel;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/enginemodel/concepts/EngineModelTest.java b/model/src/test/java/org/onap/policy/apex/model/enginemodel/concepts/EngineModelTest.java
new file mode 100644
index 000000000..c23687bb1
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/enginemodel/concepts/EngineModelTest.java
@@ -0,0 +1,176 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.enginemodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+
+/**
+ * Test engine models.
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class EngineModelTest {
+
+ @Test
+ public void testEnginetModel() {
+ assertNotNull(new AxEngineModel());
+ assertNotNull(new AxEngineModel(new AxArtifactKey()));
+ assertNotNull(new AxEngineModel(new AxArtifactKey(), new AxContextSchemas(), new AxKeyInformation(),
+ new AxContextAlbums()));
+ assertNotNull(new AxEngineModel(new AxArtifactKey(), new AxContextSchemas(), new AxKeyInformation(),
+ new AxContextAlbums(), AxEngineState.UNDEFINED, new AxEngineStats()));
+
+ final AxArtifactKey modelKey = new AxArtifactKey("ModelName", "0.0.1");
+ final AxArtifactKey schemasKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxArtifactKey albumKey = new AxArtifactKey("AlbumKey", "0.0.1");
+ final AxArtifactKey keyInfoKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxEngineStats stats = new AxEngineStats(new AxReferenceKey(modelKey, "EngineStats"));
+ final AxEngineStats otherStats = new AxEngineStats();
+ otherStats.setAverageExecutionTime(100);
+
+ final AxEngineModel model = new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, stats);
+ model.register();
+
+ assertThatThrownBy(() -> model.setKey(null))
+ .hasMessage("key may not be null");
+ model.setKey(modelKey);
+ assertEquals("ModelName:0.0.1", model.getKey().getId());
+ assertEquals("ModelName:0.0.1", model.getKeys().get(0).getId());
+
+ final long timestamp = System.currentTimeMillis();
+ model.setTimestamp(timestamp);
+ assertEquals(timestamp, model.getTimestamp());
+ model.setTimestamp(-1);
+ assertTrue(model.getTimeStampString().matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}"));
+
+ assertThatThrownBy(() -> model.setState(null))
+ .hasMessage("state may not be null");
+ for (final AxEngineState state : AxEngineState.values()) {
+ model.setState(state);
+ assertEquals(state, model.getState());
+ }
+
+ model.setState(AxEngineState.READY);
+ assertEquals(AxEngineState.READY, model.getState());
+
+ assertThatThrownBy(() -> model.setStats(null))
+ .hasMessage("stats may not be null");
+ model.setStats(stats);
+ assertEquals(stats, model.getStats());
+
+ model.clean();
+ assertNotNull(model);
+ assertThat(model.toString()).startsWith("AxEngineModel:(AxContextModel(super=AxEngineModel:(key=A");
+
+ final AxEngineModel clonedModel = new AxEngineModel(model);
+
+ assertNotEquals(0, model.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(model, model); // NOSONAR
+ assertEquals(model, clonedModel);
+ assertNotEquals(model, (Object) "Hello");
+ assertNotEquals(model, new AxEngineModel(new AxArtifactKey()));
+ assertNotEquals(model, new AxEngineModel(new AxArtifactKey(), new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, stats));
+ assertNotEquals(model, new AxEngineModel(modelKey, new AxContextSchemas(), new AxKeyInformation(keyInfoKey),
+ new AxContextAlbums(albumKey), AxEngineState.READY, stats));
+ assertNotEquals(model, new AxEngineModel(modelKey, new AxContextSchemas(schemasKey), new AxKeyInformation(),
+ new AxContextAlbums(albumKey), AxEngineState.READY, stats));
+ assertNotEquals(model, new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(), AxEngineState.READY, stats));
+ assertNotEquals(model, new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.STOPPED, stats));
+ assertNotEquals(model, new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, otherStats));
+ model.setTimestamp(timestamp);
+ assertNotEquals(model, new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, stats));
+ model.setTimestamp(0);
+ assertEquals(model, new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, stats));
+
+ model.setTimestamp(-1);
+ assertEquals(0, model.compareTo(model));
+ assertEquals(0, model.compareTo(clonedModel));
+ assertNotEquals(0, model.compareTo(new AxArtifactKey()));
+ assertNotEquals(model, new AxEngineModel(new AxArtifactKey()));
+ assertNotEquals(0, model.compareTo(new AxEngineModel(new AxArtifactKey(), new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, stats)));
+ assertNotEquals(0, model.compareTo(new AxEngineModel(modelKey, new AxContextSchemas(),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, stats)));
+ assertNotEquals(0, model.compareTo(new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(), new AxContextAlbums(albumKey), AxEngineState.READY, stats)));
+ assertNotEquals(0, model.compareTo(new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(), AxEngineState.READY, stats)));
+ assertNotEquals(0, model.compareTo(new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.STOPPED, stats)));
+ assertNotEquals(0, model.compareTo(new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, otherStats)));
+ model.setTimestamp(timestamp);
+ assertNotEquals(0, model.compareTo(new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, stats)));
+ model.setTimestamp(0);
+ assertEquals(0, model.compareTo(new AxEngineModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxContextAlbums(albumKey), AxEngineState.READY, stats)));
+
+ model.setTimestamp(timestamp);
+ AxValidationResult result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.setTimestamp(-1);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.setTimestamp(timestamp);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.setState(AxEngineState.UNDEFINED);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.setState(AxEngineState.READY);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/enginemodel/concepts/EngineStatsTest.java b/model/src/test/java/org/onap/policy/apex/model/enginemodel/concepts/EngineStatsTest.java
new file mode 100644
index 000000000..3eca27c08
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/enginemodel/concepts/EngineStatsTest.java
@@ -0,0 +1,267 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.enginemodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import io.prometheus.client.CollectorRegistry;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Test the engine statistics.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class EngineStatsTest {
+ private static final Object WAIT_LOCK = new Object();
+ private static final String ENGINE_KEY = "EngineKey";
+ private static final String ENGINE_VERSION = "0.0.1";
+
+ @Test
+ public void testEngineStats() {
+ assertNotNull(new AxEngineStats());
+ assertNotNull(new AxEngineStats(new AxReferenceKey()));
+
+ final AxReferenceKey statsKey = new AxReferenceKey(ENGINE_KEY, ENGINE_VERSION, "EngineStats");
+ final AxEngineStats stats = new AxEngineStats(statsKey);
+
+ assertThatThrownBy(() -> stats.setKey(null))
+ .hasMessage("key may not be null");
+ stats.setKey(statsKey);
+ assertEquals("EngineKey:0.0.1:NULL:EngineStats", stats.getKey().getId());
+ assertEquals("EngineKey:0.0.1:NULL:EngineStats", stats.getKeys().get(0).getId());
+
+ stats.setAverageExecutionTime(123.45);
+ assertEquals(Double.valueOf(123.45), Double.valueOf(stats.getAverageExecutionTime()));
+ checkAvgExecTimeMetric(stats);
+
+ stats.setEventCount(987);
+ assertEquals(987, stats.getEventCount());
+ checkEventsCountMetric(stats);
+
+ final long lastExecutionTime = System.currentTimeMillis();
+ stats.setLastExecutionTime(lastExecutionTime);
+ assertEquals(lastExecutionTime, stats.getLastExecutionTime());
+ checkLastExecTimeMetric(stats);
+
+ final long timestamp = System.currentTimeMillis();
+ stats.setTimeStamp(timestamp);
+ assertEquals(timestamp, stats.getTimeStamp());
+ assertNotNull(stats.getTimeStampString());
+
+ final long upTime = System.currentTimeMillis() - timestamp;
+ stats.setUpTime(upTime);
+ assertEquals(upTime, stats.getUpTime());
+ checkUpTimeMetric(stats);
+
+ stats.engineStart();
+ assertTrue(stats.getUpTime() > -1);
+ checkEngineStartTimestampMetric(stats);
+ checkLastExecTimeMetric(stats);
+ stats.engineStop();
+ assertTrue(stats.getUpTime() >= 0);
+
+ stats.engineStop();
+ checkUpTimeMetric(stats);
+ checkEngineStartTimestampMetric(stats);
+
+ stats.reset();
+
+ stats.setEventCount(-2);
+ stats.executionEnter(new AxArtifactKey());
+ assertEquals(2, stats.getEventCount());
+ checkEventsCountMetric(stats);
+
+ stats.setEventCount(10);
+ stats.executionEnter(new AxArtifactKey());
+ assertEquals(11, stats.getEventCount());
+ checkEventsCountMetric(stats);
+
+ stats.reset();
+ stats.engineStart();
+ stats.setEventCount(4);
+ checkUpTimeMetric(stats);
+ stats.executionEnter(new AxArtifactKey());
+ checkEventsCountMetric(stats);
+ checkAvgExecTimeMetric(stats);
+ checkEngineStartTimestampMetric(stats);
+
+ synchronized (WAIT_LOCK) {
+ try {
+ WAIT_LOCK.wait(10);
+ } catch (InterruptedException e) {
+ fail("test should not throw an exception");
+ }
+ }
+
+ stats.executionExit();
+ final double avExecutionTime = stats.getAverageExecutionTime();
+ assertTrue(avExecutionTime >= 2.0 && avExecutionTime < 10.0);
+ stats.engineStop();
+ checkUpTimeMetric(stats);
+
+ AxValidationResult result = new AxValidationResult();
+ result = stats.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ stats.setKey(new AxReferenceKey());
+ result = new AxValidationResult();
+ result = stats.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ stats.setKey(statsKey);
+ result = new AxValidationResult();
+ result = stats.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ stats.clean();
+ stats.reset();
+ checkAllPrometheusMetrics(stats);
+
+ final AxEngineStats clonedStats = new AxEngineStats(stats);
+ assertEquals("AxEngineStats:(engineKey=AxReferenceKey:(parentKey", clonedStats.toString().substring(0, 50));
+
+ assertNotNull(stats.getKeys());
+
+ assertNotEquals(0, stats.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(stats, stats); // NOSONAR
+ assertEquals(stats, clonedStats);
+ assertNotNull(stats);
+ checkAllPrometheusMetrics(clonedStats);
+
+ Object helloObject = "Hello";
+ assertNotEquals(stats, helloObject);
+ assertNotEquals(stats, new AxEngineStats(new AxReferenceKey()));
+
+ assertEquals(0, stats.compareTo(stats));
+ assertEquals(0, stats.compareTo(clonedStats));
+ assertNotEquals(0, stats.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, stats.compareTo(null));
+ assertNotEquals(0, stats.compareTo(new AxEngineStats(new AxReferenceKey())));
+
+ stats.setTimeStamp(1);
+ assertNotEquals(stats, new AxEngineStats(statsKey));
+ assertNotEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+ stats.setTimeStamp(0);
+ assertEquals(stats, new AxEngineStats(statsKey));
+ assertEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+ checkAllPrometheusMetrics(clonedStats);
+
+ stats.setEventCount(1);
+ assertNotEquals(stats, new AxEngineStats(statsKey));
+ assertNotEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+ stats.setEventCount(0);
+ assertEquals(stats, new AxEngineStats(statsKey));
+ assertEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+
+ stats.setLastExecutionTime(1);
+ assertNotEquals(stats, new AxEngineStats(statsKey));
+ assertNotEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+ stats.setLastExecutionTime(0);
+ assertEquals(stats, new AxEngineStats(statsKey));
+ assertEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+
+ stats.setAverageExecutionTime(1);
+ assertNotEquals(stats, new AxEngineStats(statsKey));
+ assertNotEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+ stats.setAverageExecutionTime(0);
+ assertEquals(stats, new AxEngineStats(statsKey));
+ assertEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+
+ stats.setUpTime(1);
+ assertNotEquals(stats, new AxEngineStats(statsKey));
+ assertNotEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+ stats.setUpTime(0);
+ assertEquals(stats, new AxEngineStats(statsKey));
+ assertEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+
+ assertEquals(-1, stats.compareTo(new AxEngineStats(statsKey, 0, 0, 0, 0.0, 0, 1)));
+
+ stats.engineStart();
+ assertNotEquals(stats, new AxEngineStats(statsKey));
+ final AxEngineStats newStats = new AxEngineStats(statsKey);
+ newStats.setTimeStamp(stats.getTimeStamp());
+ assertNotEquals(stats, newStats);
+ assertNotEquals(0, stats.compareTo(newStats));
+ stats.engineStop();
+ checkUpTimeMetric(stats);
+ checkEngineStartTimestampMetric(stats);
+ stats.reset();
+ assertEquals(stats, new AxEngineStats(statsKey));
+ assertEquals(0, stats.compareTo(new AxEngineStats(statsKey)));
+ checkAllPrometheusMetrics(stats);
+ }
+
+ private void checkUpTimeMetric(AxEngineStats stats) {
+ Double upTimeMetric = CollectorRegistry.defaultRegistry.getSampleValue("pdpa_engine_uptime",
+ new String[]{AxEngineStats.ENGINE_INSTANCE_ID}, new String[]{ENGINE_KEY + ":" + ENGINE_VERSION}) * 1000d;
+ assertEquals(upTimeMetric.longValue(), stats.getUpTime());
+ }
+
+ private void checkEventsCountMetric(AxEngineStats stats) {
+ Double eventsCountMetric = CollectorRegistry.defaultRegistry.getSampleValue("pdpa_engine_event_executions",
+ new String[]{AxEngineStats.ENGINE_INSTANCE_ID}, new String[]{ENGINE_KEY + ":" + ENGINE_VERSION});
+ assertEquals(eventsCountMetric.longValue(), stats.getEventCount());
+ }
+
+ private void checkLastExecTimeMetric(AxEngineStats stats) {
+ Double lastExecTimeMetric = CollectorRegistry.defaultRegistry
+ .getSampleValue("pdpa_engine_last_execution_time_sum", new String[]{AxEngineStats.ENGINE_INSTANCE_ID},
+ new String[]{ENGINE_KEY + ":" + ENGINE_VERSION}) * 1000d;
+ assertEquals(lastExecTimeMetric.longValue(), stats.getLastExecutionTime());
+ }
+
+ private void checkEngineStartTimestampMetric(AxEngineStats stats) {
+ Double engineStartTimestampMetric = CollectorRegistry.defaultRegistry
+ .getSampleValue("pdpa_engine_last_start_timestamp_epoch",
+ new String[]{AxEngineStats.ENGINE_INSTANCE_ID}, new String[]{ENGINE_KEY + ":" + ENGINE_VERSION});
+ assertEquals(engineStartTimestampMetric.longValue(), stats.getLastStart());
+ }
+
+ private void checkAvgExecTimeMetric(AxEngineStats stats) {
+ Double avgExecTimeMetric = CollectorRegistry.defaultRegistry
+ .getSampleValue("pdpa_engine_average_execution_time_seconds",
+ new String[]{AxEngineStats.ENGINE_INSTANCE_ID},
+ new String[]{ENGINE_KEY + ":" + ENGINE_VERSION}) * 1000d;
+ assertEquals(avgExecTimeMetric, Double.valueOf(stats.getAverageExecutionTime()));
+ }
+
+ private void checkAllPrometheusMetrics(AxEngineStats stats) {
+ checkEventsCountMetric(stats);
+ checkUpTimeMetric(stats);
+ checkAvgExecTimeMetric(stats);
+ checkEngineStartTimestampMetric(stats);
+ checkEngineStartTimestampMetric(stats);
+ }
+} \ No newline at end of file
diff --git a/model/src/test/java/org/onap/policy/apex/model/enginemodel/handling/ApexEngineModelTest.java b/model/src/test/java/org/onap/policy/apex/model/enginemodel/handling/ApexEngineModelTest.java
new file mode 100644
index 000000000..e7fdd2d93
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/enginemodel/handling/ApexEngineModelTest.java
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.enginemodel.handling;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModel;
+import org.onap.policy.apex.model.enginemodel.concepts.AxEngineModel;
+
+public class ApexEngineModelTest {
+ private static final String VALID_MODEL_STRING = "***validation of model successful***";
+
+ private static final String INVALID_MODEL_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=AnEngine,version=0.0.1):"
+ + "org.onap.policy.apex.model.enginemodel.concepts.AxEngineModel:INVALID:"
+ + "AxEngineModel - state is UNDEFINED\n" + "********************************";
+
+ private static final String INVALID_MODEL_MALSTRUCTURED_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=AnEngine,version=0.0.1):"
+ + "org.onap.policy.apex.model.enginemodel.concepts.AxEngineModel:INVALID:"
+ + "AxEngineModel - timestamp is not set\n" + "AxArtifactKey:(name=AnEngine,version=0.0.1):"
+ + "org.onap.policy.apex.model.enginemodel.concepts.AxEngineModel:INVALID:"
+ + "AxEngineModel - state is UNDEFINED\n" + "********************************";
+
+ TestApexModel<AxEngineModel> testApexModel;
+
+ /**
+ * Set up the test.
+ *
+ * @throws Exception errors from test setup
+ */
+ @Before
+ public void setup() throws Exception {
+ testApexModel = new TestApexModel<AxEngineModel>(AxEngineModel.class, new DummyTestApexEngineModelCreator());
+ }
+
+ @Test
+ public void testModelValid() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelValid();
+ assertEquals(VALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateInvalidModel() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateInvalidModel();
+ assertEquals(INVALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateMalstructured() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateMalstructured();
+ assertEquals(INVALID_MODEL_MALSTRUCTURED_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelWriteReadJson() throws Exception {
+ testApexModel.testApexModelWriteReadJson();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/enginemodel/handling/DummyTestApexEngineModelCreator.java b/model/src/test/java/org/onap/policy/apex/model/enginemodel/handling/DummyTestApexEngineModelCreator.java
new file mode 100644
index 000000000..9e7d99b72
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/enginemodel/handling/DummyTestApexEngineModelCreator.java
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.enginemodel.handling;
+
+import java.util.UUID;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.enginemodel.concepts.AxEngineModel;
+import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState;
+import org.onap.policy.apex.model.enginemodel.concepts.AxEngineStats;
+
+public class DummyTestApexEngineModelCreator implements TestApexModelCreator<AxEngineModel> {
+
+ @Override
+ public AxEngineModel getModel() {
+ final AxContextSchema schema0 = new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.enginemodel.concepts.TestContextItem000");
+ final AxContextSchema schema1 = new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.enginemodel.concepts.TestContextItem00A");
+
+ final AxContextSchemas schemas = new AxContextSchemas(new AxArtifactKey("ContextSchemas", "0.0.1"));
+ schemas.getSchemasMap().put(schema0.getKey(), schema0);
+ schemas.getSchemasMap().put(schema1.getKey(), schema1);
+
+ final AxContextAlbum album0 =
+ new AxContextAlbum(new AxArtifactKey("contextAlbum0", "0.0.1"), "APPLICATION", true, schema1.getKey());
+
+ final AxContextAlbums albums = new AxContextAlbums(new AxArtifactKey("context", "0.0.1"));
+ albums.getAlbumsMap().put(album0.getKey(), album0);
+
+ final AxEngineModel engineModel = new AxEngineModel(new AxArtifactKey("AnEngine", "0.0.1"));
+ engineModel.setSchemas(schemas);
+ engineModel.setAlbums(albums);
+ engineModel.setTimestamp(System.currentTimeMillis());
+ engineModel.setState(AxEngineState.EXECUTING);
+ engineModel.setStats(new AxEngineStats(new AxReferenceKey(engineModel.getKey(), "EngineStats"),
+ System.currentTimeMillis(), 100, 205, 200, 12345, 9876));
+ engineModel.getKeyInformation().generateKeyInfo(engineModel);
+
+ final AxValidationResult result = new AxValidationResult();
+ engineModel.validate(result);
+
+ return engineModel;
+ }
+
+ @Override
+ public AxEngineModel getInvalidModel() {
+ final AxEngineModel engineModel = getModel();
+
+ engineModel.setTimestamp(System.currentTimeMillis());
+ engineModel.setState(AxEngineState.UNDEFINED);
+ engineModel.setStats(new AxEngineStats(new AxReferenceKey(engineModel.getKey(), "EngineStats"),
+ System.currentTimeMillis(), 100, 205, 200, 12345, 9876));
+ engineModel.getKeyInformation().generateKeyInfo(engineModel);
+
+ return engineModel;
+ }
+
+ /**
+ * Get a malstructured model.
+ */
+ public AxEngineModel getMalstructuredModel() {
+ final AxEngineModel engineModel = getModel();
+
+ engineModel.setTimestamp(-1);
+ engineModel.setState(AxEngineState.UNDEFINED);
+
+ return engineModel;
+ }
+
+ @Override
+ public AxEngineModel getObservationModel() {
+ final AxEngineModel engineModel = getModel();
+
+ final AxContextSchema schema0 = new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.enginemodel.concepts.TestContextItem000");
+ final AxContextSchema schema1 = new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.enginemodel.concepts.TestContextItem00A");
+
+ engineModel.getKeyInformation().getKeyInfoMap().put(schema0.getKey(),
+ new AxKeyInfo(schema0.getKey(), UUID.fromString("00000000-0000-0000-0000-000000000001"), ""));
+ engineModel.getKeyInformation().getKeyInfoMap().put(schema1.getKey(),
+ new AxKeyInfo(schema1.getKey(), UUID.fromString("00000000-0000-0000-0000-000000000002"), ""));
+
+ return engineModel;
+ }
+
+ @Override
+ public AxEngineModel getWarningModel() {
+ final AxEngineModel engineModel = getModel();
+
+ final AxContextSchema schema0 = new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.enginemodel.concepts.TestContextItem000");
+ final AxContextSchema schema1 = new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.enginemodel.concepts.TestContextItem00A");
+
+ engineModel.getKeyInformation().getKeyInfoMap().put(schema0.getKey(),
+ new AxKeyInfo(schema0.getKey(), UUID.fromString("00000000-0000-0000-0000-000000000000"), ""));
+ engineModel.getKeyInformation().getKeyInfoMap().put(schema1.getKey(),
+ new AxKeyInfo(schema1.getKey(), UUID.fromString("00000000-0000-0000-0000-000000000001"), ""));
+
+ return engineModel;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/EventModelTest.java b/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/EventModelTest.java
new file mode 100644
index 000000000..cdc5fecf6
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/EventModelTest.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 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.onap.policy.apex.model.eventmodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+
+/**
+ * Test event models.
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class EventModelTest {
+
+ @Test
+ public void testEventModel() {
+ assertNotNull(new AxEventModel());
+ assertNotNull(new AxEventModel(new AxArtifactKey()));
+ assertNotNull(
+ new AxEventModel(new AxArtifactKey(), new AxContextSchemas(), new AxKeyInformation(), new AxEvents()));
+
+ final AxArtifactKey modelKey = new AxArtifactKey("ModelKey", "0.0.1");
+ final AxArtifactKey schemasKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxArtifactKey eventsKey = new AxArtifactKey("EventsKey", "0.0.1");
+ final AxArtifactKey keyInfoKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxEventModel model = new AxEventModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey));
+ model.register();
+
+ model.clean();
+ assertNotNull(model);
+ assertEquals("AxEventModel:(AxEventModel:(key=AxArtifactKey:(nam", model.toString().substring(0, 50));
+
+ final AxEventModel clonedModel = new AxEventModel(model);
+
+ assertNotEquals(0, model.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(model, model); // NOSONAR
+ assertEquals(model, clonedModel);
+ assertNotEquals(model, (Object) "Hello");
+ assertNotEquals(model, new AxEventModel(new AxArtifactKey()));
+ assertNotEquals(model, new AxEventModel(modelKey, new AxContextSchemas(), new AxKeyInformation(keyInfoKey),
+ new AxEvents(eventsKey)));
+ assertNotEquals(model, new AxEventModel(modelKey, new AxContextSchemas(schemasKey), new AxKeyInformation(),
+ new AxEvents(eventsKey)));
+ assertNotEquals(model, new AxEventModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents()));
+ assertEquals(model, new AxEventModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey)));
+
+ assertEquals(0, model.compareTo(model));
+ assertEquals(0, model.compareTo(clonedModel));
+ assertNotEquals(0, model.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, model.compareTo(new AxEventModel(modelKey, new AxContextSchemas(),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey))));
+ assertNotEquals(0, model.compareTo(new AxEventModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(), new AxEvents(eventsKey))));
+ assertNotEquals(0, model.compareTo(new AxEventModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents())));
+ assertEquals(0, model.compareTo(new AxEventModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey))));
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/EventsTest.java b/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/EventsTest.java
new file mode 100644
index 000000000..7062fcb3c
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/EventsTest.java
@@ -0,0 +1,323 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.eventmodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxToscaPolicyProcessingStatus;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Test events.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class EventsTest {
+
+ @Test
+ public void testEvents() {
+ final TreeMap<String, AxField> parameterMap = new TreeMap<>();
+ final TreeMap<String, AxField> parameterMapEmpty = new TreeMap<>();
+
+ assertNotNull(new AxEvent());
+ assertNotNull(new AxEvent(new AxArtifactKey()));
+ assertNotNull(new AxEvent(new AxArtifactKey(), "namespace"));
+ assertNotNull(new AxEvent(new AxArtifactKey(), "namespace", "source", "target"));
+ assertNotNull(new AxEvent(new AxArtifactKey(), "namespace", "source", "target"));
+ assertNotNull(new AxEvent(new AxArtifactKey(), "namespace", "source", "target", parameterMap, ""));
+
+ final AxEvent event = new AxEvent();
+
+ final AxArtifactKey eventKey = new AxArtifactKey("EventName", "0.0.1");
+ event.setKey(eventKey);
+ assertEquals("EventName:0.0.1", event.getKey().getId());
+ assertEquals("EventName:0.0.1", event.getKeys().get(0).getId());
+
+ event.setNameSpace("namespace");
+ assertEquals("namespace", event.getNameSpace());
+
+ event.setSource("source");
+ assertEquals("source", event.getSource());
+
+ event.setTarget("target");
+ assertEquals("target", event.getTarget());
+
+ event.setParameterMap(parameterMap);
+ assertEquals(0, event.getParameterMap().size());
+
+ event.setToscaPolicyState(AxToscaPolicyProcessingStatus.ENTRY.name());
+ assertEquals(AxToscaPolicyProcessingStatus.ENTRY.name(), event.getToscaPolicyState());
+
+ final AxField eventField =
+ new AxField(new AxReferenceKey(eventKey, "Field0"), new AxArtifactKey("Field0Schema", "0.0.1"));
+ event.getParameterMap().put(eventField.getKey().getLocalName(), eventField);
+ assertEquals(1, event.getParameterMap().size());
+
+ final AxField eventFieldBadParent =
+ new AxField(new AxReferenceKey(new AxArtifactKey("OtherEvent", "0.0.01"), "Field0"),
+ new AxArtifactKey("Field0Schema", "0.0.1"));
+
+ final AxArtifactKey newEventKey = new AxArtifactKey("NewEventName", "0.0.1");
+ event.setKey(newEventKey);
+ assertEquals("NewEventName:0.0.1", event.getKey().getId());
+ assertEquals("NewEventName:0.0.1", event.getKeys().get(0).getId());
+ assertEquals("NewEventName:0.0.1",
+ event.getParameterMap().get("Field0").getKey().getParentArtifactKey().getId());
+ event.setKey(eventKey);
+ assertEquals("EventName:0.0.1", event.getKey().getId());
+ assertEquals("EventName:0.0.1", event.getKeys().get(0).getId());
+
+ assertTrue("Field0", event.getFields().contains(eventField));
+ assertTrue(event.hasFields(new TreeSet<AxField>(parameterMap.values())));
+
+ AxValidationResult result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ event.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ event.setKey(eventKey);
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ event.setNameSpace("");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.WARNING, result.getValidationResult());
+
+ event.setNameSpace("namespace");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ event.setSource("");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ event.setSource("source");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ event.setTarget("");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ event.setTarget("target");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ event.getParameterMap().put(AxKey.NULL_KEY_NAME, null);
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ event.getParameterMap().remove(AxKey.NULL_KEY_NAME);
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ event.getParameterMap().put("NullField", null);
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ event.getParameterMap().remove("NullField");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ event.getParameterMap().put("NullField", eventField);
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ event.getParameterMap().remove("NullField");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ event.getParameterMap().put("BadParent", eventFieldBadParent);
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ event.getParameterMap().remove("BadParent");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ event.setToscaPolicyState("invalid_enum");
+ result = new AxValidationResult();
+ result = event.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+ event.setToscaPolicyState(AxToscaPolicyProcessingStatus.ENTRY.name());
+
+ event.clean();
+ event.buildReferences();
+ assertNotEquals(AxKey.NULL_KEY_NAME,
+ event.getParameterMap().values().iterator().next().getKey().getParentKeyName());
+
+ final AxEvent clonedEvent = new AxEvent(event);
+ assertEquals("AxEvent:(key=AxArtifactKey:(name=EventName,version=0.0.1),nameSpace=namespace",
+ clonedEvent.toString().substring(0, 77));
+
+ assertNotEquals(0, event.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(event, event); // NOSONAR
+ assertEquals(event, clonedEvent);
+ assertNotNull(event);
+
+ Object helloObj = "Hello";
+ assertNotEquals(event, helloObj);
+ assertNotEquals(event, new AxEvent(AxArtifactKey.getNullKey(), "namespace", "source", "target", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name()));
+ assertNotEquals(event, new AxEvent(eventKey, "namespace1", "source", "target", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name()));
+ assertNotEquals(event, new AxEvent(eventKey, "namespace", "source2", "target", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name()));
+ assertNotEquals(event, new AxEvent(eventKey, "namespace", "source", "target3", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name()));
+ assertNotEquals(event, new AxEvent(eventKey, "namespace", "source", "target", parameterMapEmpty,
+ AxToscaPolicyProcessingStatus.ENTRY.name()));
+ assertEquals(event, new AxEvent(eventKey, "namespace", "source", "target", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name()));
+
+ assertEquals(0, event.compareTo(event));
+ assertEquals(0, event.compareTo(clonedEvent));
+ assertNotEquals(0, event.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, event.compareTo(null));
+ assertNotEquals(0, event.compareTo(new AxEvent(AxArtifactKey.getNullKey(), "namespace", "source", "target",
+ parameterMap, AxToscaPolicyProcessingStatus.ENTRY.name())));
+ assertNotEquals(0, event.compareTo(new AxEvent(eventKey, "namespace1", "source", "target", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name())));
+ assertNotEquals(0, event.compareTo(new AxEvent(eventKey, "namespace", "source2", "target", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name())));
+ assertNotEquals(0, event.compareTo(new AxEvent(eventKey, "namespace", "source", "target3", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name())));
+ assertNotEquals(0, event.compareTo(new AxEvent(eventKey, "namespace", "source", "target", parameterMapEmpty,
+ AxToscaPolicyProcessingStatus.ENTRY.name())));
+ assertEquals(0, event.compareTo(new AxEvent(eventKey, "namespace", "source", "target", parameterMap,
+ AxToscaPolicyProcessingStatus.ENTRY.name())));
+
+ assertNotNull(event.getKeys());
+
+ final AxEvents events = new AxEvents();
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ // Invalid, no events in event map
+ events.setKey(new AxArtifactKey("EventsKey", "0.0.1"));
+ assertEquals("EventsKey:0.0.1", events.getKey().getId());
+
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ events.getEventMap().put(eventKey, event);
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ events.getEventMap().put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ events.getEventMap().remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ events.getEventMap().put(new AxArtifactKey("NullValueKey", "0.0.1"), null);
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ events.getEventMap().remove(new AxArtifactKey("NullValueKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ events.getEventMap().put(new AxArtifactKey("BadEventKey", "0.0.1"), event);
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ events.getEventMap().remove(new AxArtifactKey("BadEventKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = events.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ events.clean();
+ event.buildReferences();
+ assertNotEquals(AxKey.NULL_KEY_NAME,
+ event.getParameterMap().values().iterator().next().getKey().getParentKeyName());
+
+ final AxEvents clonedEvents = new AxEvents(events);
+ assertEquals("AxEvents:(key=AxArtifactKey:(name=EventsKey,version=0.0.1),e",
+ clonedEvents.toString().substring(0, 60));
+
+ assertNotEquals(0, events.hashCode());
+
+ assertEquals(events, clonedEvents);
+ assertNotNull(events);
+ assertNotEquals(event, helloObj);
+ assertNotEquals(events, new AxEvents(new AxArtifactKey()));
+
+ assertEquals(0, events.compareTo(events));
+ assertEquals(0, events.compareTo(clonedEvents));
+ assertNotEquals(0, events.compareTo(null));
+ assertNotEquals(0, events.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, events.compareTo(new AxEvents(new AxArtifactKey())));
+
+ clonedEvents.get(eventKey).setSource("AnotherSource");
+ assertNotEquals(0, events.compareTo(clonedEvents));
+
+ assertEquals(events.getKey(), events.getKeys().get(0));
+
+ assertEquals("EventName", events.get("EventName").getKey().getName());
+ assertEquals("EventName", events.get("EventName", "0.0.1").getKey().getName());
+ assertEquals(1, events.getAll("EventName", "0.0.1").size());
+ assertEquals(0, events.getAll("NonExistantEventsName").size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/FieldTest.java b/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/FieldTest.java
new file mode 100644
index 000000000..6ec46dbd5
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/eventmodel/concepts/FieldTest.java
@@ -0,0 +1,134 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 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.onap.policy.apex.model.eventmodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Test fields.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class FieldTest {
+
+ @Test
+ public void testField() {
+ assertNotNull(new AxField());
+ assertNotNull(new AxField(new AxReferenceKey()));
+ assertNotNull(new AxField(new AxReferenceKey(), new AxArtifactKey()));
+ assertNotNull(new AxField(new AxReferenceKey(), new AxArtifactKey(), false));
+ assertNotNull(new AxField("LocalName", new AxArtifactKey(), false));
+ assertNotNull(new AxField("LocalName", new AxArtifactKey()));
+ assertNotNull(new AxField("LocalName", new AxArtifactKey(), false));
+
+ assertNotNull(new AxInputField());
+ assertNotNull(new AxInputField(new AxReferenceKey()));
+ assertNotNull(new AxInputField(new AxReferenceKey(), new AxArtifactKey()));
+ assertNotNull(new AxInputField(new AxReferenceKey(), new AxArtifactKey(), true));
+ assertNotNull(new AxInputField("LocalName", new AxArtifactKey()));
+ assertNotNull(new AxInputField(new AxInputField()));
+
+ assertNotNull(new AxOutputField());
+ assertNotNull(new AxOutputField(new AxReferenceKey()));
+ assertNotNull(new AxOutputField(new AxReferenceKey(), new AxArtifactKey()));
+ assertNotNull(new AxOutputField(new AxReferenceKey(), new AxArtifactKey(), false));
+ assertNotNull(new AxOutputField("LocalName", new AxArtifactKey()));
+ assertNotNull(new AxOutputField(new AxOutputField()));
+
+ final AxField field = new AxField();
+
+ final AxReferenceKey fieldKey = new AxReferenceKey("FieldName", "0.0.1", "PLN", "LN");
+ field.setKey(fieldKey);
+ assertEquals("FieldName:0.0.1:PLN:LN", field.getKey().getId());
+ assertEquals("FieldName:0.0.1:PLN:LN", field.getKeys().get(0).getId());
+
+ final AxArtifactKey schemaKey = new AxArtifactKey("SchemaName", "0.0.1");
+ field.setSchema(schemaKey);
+ assertEquals("SchemaName:0.0.1", field.getSchema().getId());
+
+ assertEquals(false, field.getOptional());
+ field.setOptional(true);
+ assertEquals(true, field.getOptional());
+
+ AxValidationResult result = new AxValidationResult();
+ result = field.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ field.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = field.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ field.setKey(fieldKey);
+ result = new AxValidationResult();
+ result = field.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ field.setSchema(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = field.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ field.setSchema(schemaKey);
+ result = new AxValidationResult();
+ result = field.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ field.clean();
+
+ final AxField clonedField = new AxField(field);
+ assertEquals("AxField:(key=AxReferenceKey:(parentKeyName=FieldName,parentKeyVersion=0.0.1,"
+ + "parentLocalName=PLN,localName=LN),fieldSchemaKey="
+ + "AxArtifactKey:(name=SchemaName,version=0.0.1),optional=true)", clonedField.toString());
+
+ assertNotEquals(0, field.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(field, field); // NOSONAR
+ assertEquals(field, clonedField);
+ assertNotNull(field);
+ assertNotEquals(field, (Object) "Hello");
+ assertNotEquals(field, new AxField(AxReferenceKey.getNullKey(), AxArtifactKey.getNullKey(), false));
+ assertNotEquals(field, new AxField(fieldKey, AxArtifactKey.getNullKey(), false));
+ assertNotEquals(field, new AxField(fieldKey, schemaKey, false));
+ assertEquals(field, new AxField(fieldKey, schemaKey, true));
+
+ assertEquals(0, field.compareTo(field));
+ assertEquals(0, field.compareTo(clonedField));
+ assertNotEquals(0, field.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, field.compareTo(null));
+ assertNotEquals(0,
+ field.compareTo(new AxField(AxReferenceKey.getNullKey(), AxArtifactKey.getNullKey(), false)));
+ assertNotEquals(0, field.compareTo(new AxField(fieldKey, AxArtifactKey.getNullKey(), false)));
+ assertNotEquals(0, field.compareTo(new AxField(fieldKey, schemaKey, false)));
+ assertEquals(0, field.compareTo(new AxField(fieldKey, schemaKey, true)));
+
+ assertNotNull(field.getKeys());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/eventmodel/handling/ApexEventModelTest.java b/model/src/test/java/org/onap/policy/apex/model/eventmodel/handling/ApexEventModelTest.java
new file mode 100644
index 000000000..21b97c454
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/eventmodel/handling/ApexEventModelTest.java
@@ -0,0 +1,279 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.eventmodel.handling;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModel;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEventModel;
+
+public class ApexEventModelTest {
+ private static final String VALID_MODEL_STRING = "***validation of model successful***";
+
+ private static final String OBSERVATION_MODEL_STRING = "\n"
+ + "***observations noted during validation of model***\n"
+ + "AxArtifactKey:(name=event0,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event0,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "AxArtifactKey:(name=event2,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event2,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "********************************";
+
+ private static final String WARNING_MODEL_STRING = "\n" + "***warnings issued during validation of model***\n"
+ + "AxArtifactKey:(name=event0,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:WARNING:nameSpace on event is blank\n"
+ + "AxArtifactKey:(name=event0,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event0,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:WARNING:nameSpace on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "AxArtifactKey:(name=event2,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:WARNING:nameSpace on event is blank\n"
+ + "AxArtifactKey:(name=event2,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event2,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "********************************";
+
+ private static final String INVALID_MODEL_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1):"
+ + "org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation:INVALID:"
+ + "keyInfoMap may not be empty\n" + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=smallEventModel,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=Schemas,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=BigIntType,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=BooleanType,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=IntType,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=MapType,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=SetType,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=StringType,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=smallEventMap,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=event0,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=par0)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=par1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=par2)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=par3)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=par4)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=par5)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=par6)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=event1,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=theOnlyPar)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "duplicate key AxArtifactKey:(name=event1,version=0.0.1) found\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=event1,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "duplicate key AxReferenceKey:(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,"
+ + "localName=theOnlyPar) found\n" + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=theOnlyPar)\n"
+ + "AxArtifactKey:(name=event0,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event0,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:INVALID:"
+ + "parent key on parameter field AxReferenceKey:(parentKeyName=event0,parentKeyVersion=0.0.1,"
+ + "parentLocalName=NULL,localName=theOnlyPar) does not equal event key\n"
+ + "AxArtifactKey:(name=smallEventMap,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvents:INVALID:"
+ + "key on event entry key AxArtifactKey:(name=event2,version=0.0.1) does not equal event value key "
+ + "AxArtifactKey:(name=event1,version=0.0.1)\n" + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:INVALID:"
+ + "parent key on parameter field AxReferenceKey:(parentKeyName=event0,parentKeyVersion=0.0.1,"
+ + "parentLocalName=NULL,localName=theOnlyPar) does not equal event key\n"
+ + "********************************";
+
+ private static final String INVALID_MODEL_MALSTRUCTURED_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1):"
+ + "org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation:INVALID:"
+ + "keyInfoMap may not be empty\n" + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=smallEventModel,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=Schemas,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=SetType,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=smallEventMap,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=event1,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=theOnlyPar)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "duplicate key AxArtifactKey:(name=event1,version=0.0.1) found\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=event1,version=0.0.1)\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "duplicate key AxReferenceKey:(parentKeyName=event1,parentKeyVersion=0.0.1,"
+ + "parentLocalName=NULL,localName=theOnlyPar) found\n"
+ + "AxArtifactKey:(name=smallEventModel,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEventModel:INVALID:"
+ + "key information not found for parent key of key AxReferenceKey:"
+ + "(parentKeyName=event1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=theOnlyPar)\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "AxArtifactKey:(name=smallEventMap,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvents:INVALID:"
+ + "key on event entry key AxArtifactKey:(name=event2,version=0.0.1) does not equal event value key "
+ + "AxArtifactKey:(name=event1,version=0.0.1)\n" + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:source on event is blank\n"
+ + "AxArtifactKey:(name=event1,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvent:OBSERVATION:target on event is blank\n"
+ + "********************************";
+
+ TestApexModel<AxEventModel> testApexModel;
+
+ /**
+ * Set up the test.
+ *
+ * @throws Exception exceptions from the test
+ */
+ @Before
+ public void setup() throws Exception {
+ testApexModel = new TestApexModel<AxEventModel>(AxEventModel.class, new DummyTestApexEventModelCreator());
+ }
+
+ @Test
+ public void testModelValid() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelValid();
+ assertEquals(VALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testApexModelVaidateObservation() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateObservation();
+ assertEquals(OBSERVATION_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testApexModelVaidateWarning() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateWarning();
+ assertEquals(WARNING_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateInvalidModel() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateInvalidModel();
+ assertEquals(INVALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateMalstructured() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateMalstructured();
+ assertEquals(INVALID_MODEL_MALSTRUCTURED_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelWriteReadJson() throws Exception {
+ testApexModel.testApexModelWriteReadJson();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/eventmodel/handling/DummyTestApexEventModelCreator.java b/model/src/test/java/org/onap/policy/apex/model/eventmodel/handling/DummyTestApexEventModelCreator.java
new file mode 100644
index 000000000..11685a6b4
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/eventmodel/handling/DummyTestApexEventModelCreator.java
@@ -0,0 +1,309 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.eventmodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEventModel;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+
+public class DummyTestApexEventModelCreator implements TestApexModelCreator<AxEventModel> {
+
+ @Override
+ public AxEventModel getModel() {
+ final AxContextSchema axSchema0 =
+ new AxContextSchema(new AxArtifactKey("BooleanType", "0.0.1"), "Java", "java.lang.Boolean");
+ final AxContextSchema axSchema1 =
+ new AxContextSchema(new AxArtifactKey("IntType", "0.0.1"), "Java", "java.lang.Integer");
+ final AxContextSchema axSchema2 =
+ new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java", "java.lang.String");
+ final AxContextSchema axSchema3 = new AxContextSchema(new AxArtifactKey("KeyType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey");
+ final AxContextSchema axSchema4 = new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation");
+ final AxContextSchema axSchema5 =
+ new AxContextSchema(new AxArtifactKey("BigIntType", "0.0.1"), "Java", "java.math.BigInteger");
+ final AxContextSchema axSchema6 = new AxContextSchema(new AxArtifactKey("ModelType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.basicmodel.concepts.AxModel");
+
+ final AxContextSchemas dataTypes = new AxContextSchemas(new AxArtifactKey("Schemas", "0.0.1"));
+ dataTypes.getSchemasMap().put(axSchema0.getKey(), axSchema0);
+ dataTypes.getSchemasMap().put(axSchema1.getKey(), axSchema1);
+ dataTypes.getSchemasMap().put(axSchema2.getKey(), axSchema2);
+ dataTypes.getSchemasMap().put(axSchema3.getKey(), axSchema3);
+ dataTypes.getSchemasMap().put(axSchema4.getKey(), axSchema4);
+ dataTypes.getSchemasMap().put(axSchema5.getKey(), axSchema5);
+ dataTypes.getSchemasMap().put(axSchema6.getKey(), axSchema6);
+
+ final AxEvents eventMap = new AxEvents(new AxArtifactKey("smallEventMap", "0.0.1"));
+
+ final AxEvent event0 = new AxEvent(new AxArtifactKey("event0", "0.0.1"),
+ "org.onap.policy.apex.model.eventmodel.events", "Source", "Target");
+ event0.getParameterMap().put("par0",
+ new AxField(new AxReferenceKey(event0.getKey(), "par0"), axSchema0.getKey()));
+ event0.getParameterMap().put("par1",
+ new AxField(new AxReferenceKey(event0.getKey(), "par1"), axSchema1.getKey()));
+ event0.getParameterMap().put("par2",
+ new AxField(new AxReferenceKey(event0.getKey(), "par2"), axSchema2.getKey()));
+ event0.getParameterMap().put("par3",
+ new AxField(new AxReferenceKey(event0.getKey(), "par3"), axSchema6.getKey()));
+ event0.getParameterMap().put("par4",
+ new AxField(new AxReferenceKey(event0.getKey(), "par4"), axSchema4.getKey()));
+ event0.getParameterMap().put("par5",
+ new AxField(new AxReferenceKey(event0.getKey(), "par5"), axSchema5.getKey()));
+ event0.getParameterMap().put("par6",
+ new AxField(new AxReferenceKey(event0.getKey(), "par6"), axSchema5.getKey()));
+ eventMap.getEventMap().put(event0.getKey(), event0);
+
+ final AxEvent event1 = new AxEvent(new AxArtifactKey("event1", "0.0.1"),
+ "org.onap.policy.apex.model.eventmodel.events", "Source", "Target");
+ event1.getParameterMap().put("theOnlyPar",
+ new AxField(new AxReferenceKey(event1.getKey(), "theOnlyPar"), axSchema3.getKey()));
+ eventMap.getEventMap().put(event1.getKey(), event1);
+
+ final AxEvent event2 = new AxEvent(new AxArtifactKey("event2", "0.0.1"),
+ "org.onap.policy.apex.model.eventmodel.events", "Source", "Target");
+ eventMap.getEventMap().put(event2.getKey(), event2);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1"));
+
+ final AxEventModel eventModel =
+ new AxEventModel(new AxArtifactKey("EventModel", "0.0.1"), dataTypes, keyInformation, eventMap);
+ keyInformation.generateKeyInfo(eventModel);
+
+ eventModel.validate(new AxValidationResult());
+ return eventModel;
+ }
+
+ @Override
+ public AxEventModel getInvalidModel() {
+ final AxContextSchema axSchema0 =
+ new AxContextSchema(new AxArtifactKey("BooleanType", "0.0.1"), "Java", "java.lang.Zoolean");
+ final AxContextSchema axSchema1 =
+ new AxContextSchema(new AxArtifactKey("IntType", "0.0.1"), "Java", "java.lang.Integer");
+ final AxContextSchema axSchema2 =
+ new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java", "java.lang.String");
+ final AxContextSchema axSchema3 =
+ new AxContextSchema(new AxArtifactKey("SetType", "0.0.1"), "Java", "java.util.Set");
+ final AxContextSchema axSchema4 =
+ new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java", "java.util.Map");
+ final AxContextSchema axSchema5 =
+ new AxContextSchema(new AxArtifactKey("BigIntType", "0.0.1"), "Java", "java.math.BigInteger");
+
+ final AxContextSchemas dataTypes = new AxContextSchemas(new AxArtifactKey("Schemas", "0.0.1"));
+ dataTypes.getSchemasMap().put(axSchema0.getKey(), axSchema0);
+ dataTypes.getSchemasMap().put(axSchema1.getKey(), axSchema1);
+ dataTypes.getSchemasMap().put(axSchema2.getKey(), axSchema2);
+ dataTypes.getSchemasMap().put(axSchema3.getKey(), axSchema3);
+ dataTypes.getSchemasMap().put(axSchema4.getKey(), axSchema4);
+ dataTypes.getSchemasMap().put(axSchema5.getKey(), axSchema5);
+
+ final AxEvents eventMap = new AxEvents(new AxArtifactKey("smallEventMap", "0.0.1"));
+
+ final AxEvent event0 =
+ new AxEvent(new AxArtifactKey("event0", "0.0.1"), "org.onap.policy.apex.model.eventmodel.events");
+ event0.getParameterMap().put("par0",
+ new AxField(new AxReferenceKey(event0.getKey(), "par0"), axSchema0.getKey()));
+ event0.getParameterMap().put("par1",
+ new AxField(new AxReferenceKey(event0.getKey(), "par1"), axSchema1.getKey()));
+ event0.getParameterMap().put("par2",
+ new AxField(new AxReferenceKey(event0.getKey(), "par2"), axSchema2.getKey()));
+ event0.getParameterMap().put("par3",
+ new AxField(new AxReferenceKey(event0.getKey(), "par3"), axSchema3.getKey()));
+ event0.getParameterMap().put("par4",
+ new AxField(new AxReferenceKey(event0.getKey(), "par4"), axSchema4.getKey()));
+ event0.getParameterMap().put("par5",
+ new AxField(new AxReferenceKey(event0.getKey(), "par5"), axSchema5.getKey()));
+ event0.getParameterMap().put("par6",
+ new AxField(new AxReferenceKey(event0.getKey(), "par6"), axSchema5.getKey()));
+ eventMap.getEventMap().put(event0.getKey(), event0);
+
+ final AxEvent event1 =
+ new AxEvent(new AxArtifactKey("event1", "0.0.1"), "org.onap.policy.apex.model.eventmodel.events");
+ event1.getParameterMap().put("theOnlyPar",
+ new AxField(new AxReferenceKey(event0.getKey(), "theOnlyPar"), axSchema3.getKey()));
+ eventMap.getEventMap().put(event1.getKey(), event1);
+
+ final AxEvent event2 =
+ new AxEvent(new AxArtifactKey("event2", "0.0.1"), "org.onap.policy.apex.model.eventmodel.events");
+ eventMap.getEventMap().put(event2.getKey(), event1);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1"));
+
+ final AxEventModel eventModel =
+ new AxEventModel(new AxArtifactKey("smallEventModel", "0.0.1"), dataTypes, keyInformation, eventMap);
+
+ return eventModel;
+ }
+
+ @Override
+ public AxEventModel getMalstructuredModel() {
+ final AxContextSchema axSchema3 =
+ new AxContextSchema(new AxArtifactKey("SetType", "0.0.1"), "Java", "java.util.Set");
+ final AxContextSchemas dataTypes = new AxContextSchemas(new AxArtifactKey("Schemas", "0.0.1"));
+ dataTypes.getSchemasMap().put(axSchema3.getKey(), axSchema3);
+
+ final AxEvents eventMap = new AxEvents(new AxArtifactKey("smallEventMap", "0.0.1"));
+
+ final AxEvent event1 =
+ new AxEvent(new AxArtifactKey("event1", "0.0.1"), "org.onap.policy.apex.model.eventmodel.events");
+ event1.getParameterMap().put("theOnlyPar",
+ new AxField(new AxReferenceKey(event1.getKey(), "theOnlyPar"), axSchema3.getKey()));
+ eventMap.getEventMap().put(event1.getKey(), event1);
+
+ final AxEvent event2 =
+ new AxEvent(new AxArtifactKey("event2", "0.0.1"), "org.onap.policy.apex.model.eventmodel.events");
+ eventMap.getEventMap().put(event2.getKey(), event1);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1"));
+
+ final AxEventModel eventModel =
+ new AxEventModel(new AxArtifactKey("smallEventModel", "0.0.1"), dataTypes, keyInformation, eventMap);
+
+ eventModel.validate(new AxValidationResult());
+
+ return eventModel;
+ }
+
+ @Override
+ public AxEventModel getWarningModel() {
+ final AxContextSchema axSchema0 =
+ new AxContextSchema(new AxArtifactKey("BooleanType", "0.0.1"), "Java", "java.lang.Boolean");
+ final AxContextSchema axSchema1 =
+ new AxContextSchema(new AxArtifactKey("IntType", "0.0.1"), "Java", "java.lang.Integer");
+ final AxContextSchema axSchema2 =
+ new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java", "java.lang.String");
+ final AxContextSchema axSchema3 =
+ new AxContextSchema(new AxArtifactKey("SetType", "0.0.1"), "Java", "java.util.Set");
+ final AxContextSchema axSchema4 =
+ new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java", "java.util.Map");
+ final AxContextSchema axSchema5 =
+ new AxContextSchema(new AxArtifactKey("BigIntType", "0.0.1"), "Java", "java.math.BigInteger");
+ final AxContextSchemas dataTypes = new AxContextSchemas(new AxArtifactKey("Schemas", "0.0.1"));
+ dataTypes.getSchemasMap().put(axSchema0.getKey(), axSchema0);
+ dataTypes.getSchemasMap().put(axSchema1.getKey(), axSchema1);
+ dataTypes.getSchemasMap().put(axSchema2.getKey(), axSchema2);
+ dataTypes.getSchemasMap().put(axSchema3.getKey(), axSchema3);
+ dataTypes.getSchemasMap().put(axSchema4.getKey(), axSchema4);
+ dataTypes.getSchemasMap().put(axSchema5.getKey(), axSchema5);
+
+ final AxEvents eventMap = new AxEvents(new AxArtifactKey("smallEventMap", "0.0.1"));
+
+ final AxEvent event0 = new AxEvent(new AxArtifactKey("event0", "0.0.1"), "");
+ event0.getParameterMap().put("par0",
+ new AxField(new AxReferenceKey(event0.getKey(), "par0"), axSchema0.getKey()));
+ event0.getParameterMap().put("par1",
+ new AxField(new AxReferenceKey(event0.getKey(), "par1"), axSchema1.getKey()));
+ event0.getParameterMap().put("par2",
+ new AxField(new AxReferenceKey(event0.getKey(), "par2"), axSchema2.getKey()));
+ event0.getParameterMap().put("par3",
+ new AxField(new AxReferenceKey(event0.getKey(), "par3"), axSchema3.getKey()));
+ event0.getParameterMap().put("par4",
+ new AxField(new AxReferenceKey(event0.getKey(), "par4"), axSchema4.getKey()));
+ event0.getParameterMap().put("par5",
+ new AxField(new AxReferenceKey(event0.getKey(), "par5"), axSchema5.getKey()));
+ eventMap.getEventMap().put(event0.getKey(), event0);
+
+ final AxEvent event1 = new AxEvent(new AxArtifactKey("event1", "0.0.1"), "");
+ event1.getParameterMap().put("theOnlyPar",
+ new AxField(new AxReferenceKey(event1.getKey(), "theOnlyPar"), axSchema3.getKey()));
+ eventMap.getEventMap().put(event1.getKey(), event1);
+
+ final AxEvent event2 = new AxEvent(new AxArtifactKey("event2", "0.0.1"), "");
+ eventMap.getEventMap().put(event2.getKey(), event2);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1"));
+
+ final AxEventModel eventModel =
+ new AxEventModel(new AxArtifactKey("smallEventModel", "0.0.1"), dataTypes, keyInformation, eventMap);
+ eventModel.getKeyInformation().generateKeyInfo(eventModel);
+ eventModel.validate(new AxValidationResult());
+
+ return eventModel;
+ }
+
+ @Override
+ public AxEventModel getObservationModel() {
+ final AxContextSchema axSchema0 =
+ new AxContextSchema(new AxArtifactKey("BooleanType", "0.0.1"), "Java", "java.lang.Boolean");
+ final AxContextSchema axSchema1 =
+ new AxContextSchema(new AxArtifactKey("IntType", "0.0.1"), "Java", "java.lang.Integer");
+ final AxContextSchema axSchema2 =
+ new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java", "java.lang.String");
+ final AxContextSchema axSchema3 =
+ new AxContextSchema(new AxArtifactKey("SetType", "0.0.1"), "Java", "java.util.Set");
+ final AxContextSchema axSchema4 =
+ new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java", "java.util.Map");
+ final AxContextSchema axSchema5 =
+ new AxContextSchema(new AxArtifactKey("BigIntType", "0.0.1"), "Java", "java.math.BigInteger");
+ final AxContextSchemas schemas = new AxContextSchemas(new AxArtifactKey("Schemas", "0.0.1"));
+ schemas.getSchemasMap().put(axSchema0.getKey(), axSchema0);
+ schemas.getSchemasMap().put(axSchema1.getKey(), axSchema1);
+ schemas.getSchemasMap().put(axSchema2.getKey(), axSchema2);
+ schemas.getSchemasMap().put(axSchema3.getKey(), axSchema3);
+ schemas.getSchemasMap().put(axSchema4.getKey(), axSchema4);
+ schemas.getSchemasMap().put(axSchema5.getKey(), axSchema5);
+
+ final AxEvents eventMap = new AxEvents(new AxArtifactKey("smallEventMap", "0.0.1"));
+
+ final AxEvent event0 =
+ new AxEvent(new AxArtifactKey("event0", "0.0.1"), "org.onap.policy.apex.model.eventmodel.events");
+ event0.getParameterMap().put("par0",
+ new AxField(new AxReferenceKey(event0.getKey(), "par0"), axSchema0.getKey()));
+ event0.getParameterMap().put("par1",
+ new AxField(new AxReferenceKey(event0.getKey(), "par1"), axSchema1.getKey()));
+ event0.getParameterMap().put("par2",
+ new AxField(new AxReferenceKey(event0.getKey(), "par2"), axSchema2.getKey()));
+ event0.getParameterMap().put("par3",
+ new AxField(new AxReferenceKey(event0.getKey(), "par3"), axSchema3.getKey()));
+ event0.getParameterMap().put("par4",
+ new AxField(new AxReferenceKey(event0.getKey(), "par4"), axSchema4.getKey()));
+ event0.getParameterMap().put("par5",
+ new AxField(new AxReferenceKey(event0.getKey(), "par5"), axSchema5.getKey()));
+ eventMap.getEventMap().put(event0.getKey(), event0);
+
+ final AxEvent event1 =
+ new AxEvent(new AxArtifactKey("event1", "0.0.1"), "org.onap.policy.apex.model.eventmodel.events");
+ event1.getParameterMap().put("theOnlyPar",
+ new AxField(new AxReferenceKey(event1.getKey(), "theOnlyPar"), axSchema3.getKey()));
+ eventMap.getEventMap().put(event1.getKey(), event1);
+
+ final AxEvent event2 =
+ new AxEvent(new AxArtifactKey("event2", "0.0.1"), "org.onap.policy.apex.model.eventmodel.events");
+ eventMap.getEventMap().put(event2.getKey(), event2);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1"));
+
+ final AxEventModel eventModel =
+ new AxEventModel(new AxArtifactKey("smallEventModel", "0.0.1"), schemas, keyInformation, eventMap);
+ eventModel.getKeyInformation().generateKeyInfo(eventModel);
+ eventModel.validate(new AxValidationResult());
+
+ return eventModel;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexApiResultTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexApiResultTest.java
new file mode 100644
index 000000000..3c2af18ea
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexApiResultTest.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Arrays;
+import org.junit.Test;
+import org.onap.policy.apex.model.modelapi.ApexApiResult.Result;
+
+/**
+ * Test API results.
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexApiResultTest {
+
+ @Test
+ public void testApiResult() {
+ assertNotNull(new ApexApiResult());
+
+ for (final Result result : Result.values()) {
+ assertNotNull(new ApexApiResult(result));
+ }
+
+ assertNotNull(new ApexApiResult(Result.SUCCESS, "Result Message"));
+ assertNotNull(new ApexApiResult(Result.FAILED, new IOException("IO Exception message")));
+ assertNotNull(new ApexApiResult(Result.FAILED, "Result Message", new IOException("IO Exception message")));
+
+ final ApexApiResult result =
+ new ApexApiResult(Result.FAILED, "Result Message", new IOException("IO Exception message"));
+
+ assertFalse(result.isOk());
+ assertTrue(result.isNok());
+ assertEquals(Result.FAILED, result.getResult());
+ assertEquals("Result Message\nIO Exception message\njava.io.IOExce", result.getMessage().substring(0, 50));
+
+ final ApexApiResult result2 = new ApexApiResult(Result.SUCCESS);
+ result2.addMessage(null);
+ assertEquals("", result2.getMessage());
+ result2.addMessage("");
+ assertEquals("", result2.getMessage());
+ result2.addMessage("funky message");
+ assertEquals("funky message\n", result2.getMessage());
+
+ result2.setResult(Result.OTHER_ERROR);
+ assertEquals(Result.OTHER_ERROR, result2.getResult());
+
+ final String[] messages = {"First Message", "Second Message", "Third Message"};
+ result2.setMessages(Arrays.asList(messages));
+ assertEquals("First Message", result2.getMessages().get(0));
+ assertEquals("Second Message", result2.getMessages().get(1));
+ assertEquals("Third Message", result2.getMessages().get(2));
+
+ assertEquals("result: OTHER_ERROR\nFirst Message\nSecond Message\nThird Message\n", result2.toString());
+ assertEquals("{\n" + "\"result\": \"OTHER_ERROR\",\n" + "\"messages\": [\n" + "\"First Message\",\n"
+ + "\"Second Message\",\n" + "\"Third Message\"]\n" + "}\n", result2.toJson());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiContextAlbumTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiContextAlbumTest.java
new file mode 100644
index 000000000..5ce6b6760
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiContextAlbumTest.java
@@ -0,0 +1,176 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Context album for API tests.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexEditorApiContextAlbumTest {
+ @Test
+ public void testContextAlbumCrud() {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = apexModel.validateContextAlbum(null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.validateContextAlbum("%%%$£", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createContextAlbum("MyMap002", "0.0.2", "APPLICATION", "true", "MapType", "0.0.1",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", "0.1.2", "ZOOBY", "false", "MapType", "0.0.1",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 012");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", "0.1.4", "UNDEFINED", null, "MapType", "0.0.1",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 014");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "+++", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapZooby", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapType", "--++", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapType", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapType", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapType", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createContextAlbum("MyMap002", "0.0.2", "APPLICATION", "true", "MapType", null,
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createContextAlbum("MyMap011", "0.1.2", "APPLICATION", "true", "MapType", "0.0.1",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.deleteContextAlbum("MyMap012", "0.1.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextAlbum("MyMap012", "0.1.2", "ZOOBY", "false", "MapType", "0.0.1",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 012");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.validateContextAlbum(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updateContextAlbum(null, null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap002", "0.0.2", null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap002", "0.0.2", "ZOOBY", "true", null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap002", "0.0.2", null, null, null, null,
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, null, "true", null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap015", null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap014", "0.1.5", null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", "StringType", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", "String", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", "StringType", "0.0.2", null,
+ null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", "StringType", "0.0.1", null,
+ null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "Hello", "StringType", "0.0.1", null,
+ null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listContextAlbum("@£%%$", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.listContextAlbum(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listContextAlbum("MyMap012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listContextAlbum("MyMap012", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listContextAlbum("MyMap012", "0.2.5");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listContextAlbum("MyMap014", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteContextAlbum("@£%%$", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.deleteContextAlbum("MyMap012", "0.1.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteContextAlbum("MyMap012oooo", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listContextAlbum("MyMap012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(3, result.getMessages().size());
+
+ result = apexModel.deleteContextAlbum("MyMap012", "0.1.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listContextAlbum("MyMap012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.deleteContextAlbum("MyMap012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.listContextAlbum("MyMap012", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteContextAlbum(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+
+ result = apexModel.listContextAlbum(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(0, result.getMessages().size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiContextSchemaTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiContextSchemaTest.java
new file mode 100644
index 000000000..20310a29e
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiContextSchemaTest.java
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Context schema for API tests.
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexEditorApiContextSchemaTest {
+ @Test
+ public void testContextSchemaCrud() {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = apexModel.validateContextSchemas(null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.validateContextSchemas("%%%$£", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listContextSchemas(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createContextSchema("Hello", "0.0.2", "Java", "java.lang.String",
+ "1fa2e430-f2b2-11e6-bc64-92361f002671", "A description of hello");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextSchema("Hello", "0.1.2", "Java", "java.lang.String",
+ "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of hola");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextSchema("Hello", "0.1.4", "Java", "java.lang.String",
+ "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of connichi wa");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextSchema("Hello", null, "Java", "java.lang.String", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextSchema("Hello", null, "Java", "java.lang.String", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.deleteContextSchema("Hello", "0.1.4");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextSchema("Hello", "0.1.4", "Java", "java.lang.String",
+ "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of connichi wa");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createContextSchema("Hello2", null, null, "java.lang.String", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createContextSchema("Hello2", null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createContextSchema("Hello2", null, "Java", "java.lang.String", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createContextSchema("Hello", "0.1.2", "Java", "java.lang.Float",
+ "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of hola");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ result = apexModel.deleteContextSchema("Hello", "0.1.4");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createContextSchema("Hello", "0.1.4", "Java", "java.lang.String",
+ "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of connichi wa");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.validateContextSchemas(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updateContextSchema(null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.updateContextSchema("Hello", "0.0.2", null, null, null, "An updated description of hello");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextSchema("Hello", "0.0.2", null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateContextSchema("Hello", "0.1.2", "Java", "java.lang.Integer",
+ "1fa2e430-f2b2-11e6-bc64-92361f002673", "A further updated description of hola");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updateContextSchema("Hello2", "0.0.2", null, null, null, "An updated description of hello");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listContextSchemas("@£%%$", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.listContextSchemas("Hello", "0.1.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.listContextSchemas("Hello", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+
+ result = apexModel.listContextSchemas(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(9, result.getMessages().size());
+
+ result = apexModel.deleteContextSchema("@£%%$", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.deleteContextSchema("Hello", "0.1.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteContextSchema("Hellooooo", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listContextSchemas("Hello", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+
+ result = apexModel.deleteContextSchema("Hello", "0.1.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listContextSchemas("Hello", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(3, result.getMessages().size());
+
+ result = apexModel.deleteContextSchema("Hello", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listContextSchemas("Hello", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listContextSchemas(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.deleteContextSchema(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(5, result.getMessages().size());
+
+ result = apexModel.listContextSchemas(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(0, result.getMessages().size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiEventTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiEventTest.java
new file mode 100644
index 000000000..ac9265e84
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiEventTest.java
@@ -0,0 +1,202 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Test events for API tests.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexEditorApiEventTest {
+ @Test
+ public void testEventCrud() {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = apexModel.validateEvent(null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.validateEvent("%%%$£", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createEvent("MyEvent002", "0.0.2", "My Namespace", "My Source", "my target",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createEvent("MyEvent012", "0.1.2", "My Namespace", "My Source", "my target",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createEvent("MyEvent012", "0.1.4", "My Namespace", "My Source", "my target",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 014", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createEvent("MyEvent012", null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createEvent("MyEvent012", null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createEvent("MyEvent002", "0.0.2", "My Namespace", "My Source", "my target",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createEvent("@£$%^", "0.2.5", "My Namespace", "My Source", "my target",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.deleteEvent("MyEvent012", "0.1.4");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createEvent("MyEvent012", "0.1.4", "My Namespace", "My Source", "my target",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 014", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.validateEvent(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updateEvent(null, null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result =
+ apexModel.updateEvent("MyEvent012", "0.1.2", "Another Namespace", null, "Another target", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateEvent("MyEvent002", "0.0.2", "My Namespace", "My Source", "my target",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateEvent("MyEvent012", null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateEvent("MyEvent015", null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateEvent("MyEvent014", "0.1.5", null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateEvent("@£$%^^", "0.6.9", null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.listEvent("@£$%", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listEvent(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listEvent("MyEvent012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listEvent("MyEvent012", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listEvent("MyEvent012", "0.2.5");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listEvent("MyEvent123", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteEvent("@£$%^", "0.1.1");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deleteEvent("MyEvent012", "0.1.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteEvent("MyEvent012oooo", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listEvent("MyEvent012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(3, result.getMessages().size());
+
+ result = apexModel.deleteEvent("MyEvent012", "0.1.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listEvent("MyEvent012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.deleteEvent("MyEvent012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listEvent("MyEvent012", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createEventPar("MyEvent123", null, "NewPar00", null, null, false);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createEventPar("MyEvent002", "4.5.6", "NewPar00", null, null, true);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createEventPar("MyEvent002", "0.1.4", "NewPar00", null, null, false);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar00", null, null, true);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.createContextSchema("eventContextItem0", "0.0.1", "Java", "java.lang.Integer",
+ "1fa2e430-f2b2-11e6-bc64-92361f002673", "A further updated description of hola");
+ result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar00", "eventContextItem0", null, false);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar00", "eventContextItem0", null, true);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar01", "eventContextItem0", "0.0.1", false);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar02", "eventContextItem0", "0.0.2", true);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createEventPar("MyEvent002", null, "NewPar02", "eventContextItem0", null, false);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createEventPar("MyEvent002", null, "NewPar03", "eventContextItem0", null, true);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listEventPar("@£%%$", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listEventPar("MyEvent002", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listEventPar("MyEvent002", "0.0.1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listEventPar("MyEvent002", "0.0.2", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listEventPar("MyEvent002", "0.0.2", "NewPar01");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listEventPar("MyEvent002", "0.0.2", "NewPar02");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listEventPar("MyEvent002", "0.0.2", "NewPar04");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteEventPar("@££%%%", "0.0.2", "NewPar04");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deleteEventPar("NonExistantEvent", "0.0.2", "NewPar04");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(4, apexModel.listEventPar("MyEvent002", null, null).getMessages().size());
+ result = apexModel.deleteEventPar("MyEvent002", "0.0.2", "NewPar04");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(4, apexModel.listEventPar("MyEvent002", null, null).getMessages().size());
+ result = apexModel.deleteEventPar("MyEvent002", null, "NewPar02");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(3, apexModel.listEventPar("MyEvent002", null, null).getMessages().size());
+ result = apexModel.deleteEventPar("MyEvent002", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listEventPar("MyEvent002", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deleteEventPar("MyEvent002", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listEventPar("MyEvent002", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteEvent(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+
+ result = apexModel.listEvent(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(0, result.getMessages().size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiKeyInfoTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiKeyInfoTest.java
new file mode 100644
index 000000000..2519b8cb2
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiKeyInfoTest.java
@@ -0,0 +1,137 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Key information for API tests.
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexEditorApiKeyInfoTest {
+
+ @Test
+ public void testKeyInfoCrud() {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = apexModel.validateKeyInformation(null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.validateKeyInformation("%%%$£", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createKeyInformation(null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.createKeyInformation("Hello", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002671",
+ "A description of hello");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createKeyInformation("Hello", "0.1.2", "1fa2e430-f2b2-11e6-bc64-92361f002672",
+ "A description of hola");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createKeyInformation("Hello", "0.1.4", "1fa2e430-f2b2-11e6-bc64-92361f002672",
+ "A description of connichi wa");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createKeyInformation("Hello", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createKeyInformation("Hello", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ result = apexModel.createKeyInformation("Hello", "0.1.2", "1fa2e430-f2b2-11e6-bc64-92361f002672",
+ "A description of hola");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ result = apexModel.validateKeyInformation(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updateKeyInformation(null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.updateKeyInformation("Hello", "0.0.2", null, "An updated description of hello");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateKeyInformation("Hello", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateKeyInformation("Hello", "0.1.2", "1fa2e430-f2b2-11e6-bc64-92361f002673",
+ "A further updated description of hola");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updateKeyInformation("Hello2", "0.0.2", null, "An updated description of hello");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listKeyInformation(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listKeyInformation("%%%$$", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.listKeyInformation("Hello", "0.1.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.listKeyInformation("Hello", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+
+ result = apexModel.deleteKeyInformation("Hello", "0.1.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteKeyInformation("Hellooooo", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listKeyInformation("Hello", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+
+ result = apexModel.listKeyInformation(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(22, result.getMessages().size());
+
+ result = apexModel.deleteKeyInformation("%%%$$", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.deleteKeyInformation("Hello", "0.1.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listKeyInformation("Hello", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(3, result.getMessages().size());
+
+ result = apexModel.deleteKeyInformation("Hello", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listKeyInformation("Hello", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteKeyInformation(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(18, result.getMessages().size());
+
+ result = apexModel.listKeyInformation(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(0, result.getMessages().size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiPolicyTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiPolicyTest.java
new file mode 100644
index 000000000..0a4d72214
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiPolicyTest.java
@@ -0,0 +1,1023 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Test policies for API.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexEditorApiPolicyTest {
+ @Test
+ public void testMyTestPolicyCrud() {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = apexModel.validatePolicy(null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.validatePolicy("%%%$£", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createPolicy("MyPolicy002", "0.0.2", "SomeTemplate", "AState",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicy("MyPolicy002", "0.0.2", "SomeTemplate", "AState",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicy("MyPolicy012", null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicy("MyPolicy012", null, "SomeTemplate", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicy("MyPolicy013", null, null, "AState", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicy("MyPolicy012", null, "SomeTemplate", "AState", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicy("MyPolicy002", "0.0.2", "SomeTemplate", "AState",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicy("MyPolicy012", "0.1.2", "SomeTemplate", "AState",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicy("MyTestPolicy", "0.0.1", "SomeTemplate", "TestState",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.deletePolicy("MyPolicy002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicy("MyPolicy002", "0.0.2", "SomeTemplate", "AState",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.validatePolicy(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updatePolicy("@£$$", "0.0.2", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicy("MyPolicy002", "0.0.2", null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicy("MyPolicy002", "0.0.1", null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicy("MyPolicy002", "0.0.2", "SomeOtherTemplate", "BState",
+ "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicy("MyPolicy012", null, "SomeOtherTemplate", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicy("MyPolicy012", null, null, "CState", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicy("MyPolicy012", null, "SomeOtherTemplate", "BState", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicy("MyPolicy015", null, "SomeOtherTemplate", "DState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicy("MyPolicy014", "0.1.5", "SomeOtherTemplate", "EState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listPolicy("@£$%%", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicy(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(6, result.getMessages().size());
+ result = apexModel.listPolicy("MyPolicy012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listPolicy("MyPolicy012", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicy("MyPolicy012", "0.2.5");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicy("MyPolicy014", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deletePolicy("@£$%", "0.1.1");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.deletePolicy("MyPolicy012", "0.1.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deletePolicy("MyPolicy012oooo", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listPolicy("MyPolicy012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.deletePolicy("MyPolicy002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+
+ result = apexModel.listPolicy("MyPolicy012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.deletePolicy("MyPolicy012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.createPolicyState(null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyState("MyPolicy123", null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyState("MyPolicy123", null, "AState", null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", "0.0.2", "AState", null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "ATrigger", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, "ATask", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "AState", "inEvent", "0.0.1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "BState", "inEvent", "0.0.1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "CState", "inEvent", "0.0.1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "DState", "inEvent", "0.0.1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updatePolicyState(null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyState("MyPolicy123", null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyState("MyPolicy123", null, "AState", null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", "0.0.2", "AState", null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", null, null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "ZState", null, null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "ATrigger", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, "ATask", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", "0.0.1", "AState", "inEvent", "0.0.1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", "0.0.1", "BState", "inEvent", "0.0.1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", "0.0.1", "CState", "inEvent", "0.0.1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyState("MyTestPolicy", "0.0.1", "DState", "inEvent", "0.0.1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listPolicyState("MyTestPolicy", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+ result = apexModel.listPolicyState(null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyState("SomeOtherPolicy", "0.0.1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyState("SomeOtherPolicy", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyState("MyTestPolicy", "0.0.2", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyState("MyTestPolicy", "0.0.1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+ result = apexModel.listPolicyState("MyTestPolicy", "0.0.1", "CState");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyState("MyTestPolicy", null, "CState");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyState("MyTestPolicy", "0.0.1", "AState");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyState("MyTestPolicy", "0.0.1", "EState");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deletePolicyState("@£$$", "0.0.2", "Trigger04");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ assertEquals(4, apexModel.listPolicyState("MyTestPolicy", null, null).getMessages().size());
+ result = apexModel.deletePolicyState("MyTestPolicy", "0.0.2", "Trigger04");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(4, apexModel.listPolicyState("MyTestPolicy", null, null).getMessages().size());
+ result = apexModel.deletePolicyState("MyTestPolicy", null, "CState");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyState("MyTestPolicy", null, "ZState");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(3, apexModel.listPolicyState("MyTestPolicy", null, null).getMessages().size());
+ result = apexModel.deletePolicyState("MyTestPolicy", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listPolicyState("MyTestPolicy", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyState("MyTestPolicy", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "TestState1", "inEvent", "0.0.1", "task",
+ "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "TestState2", "outEvent0", "0.0.1", "task",
+ "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "TestState3", "outEvent1", "0.0.1", "task",
+ "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createPolicyStateTaskSelectionLogic(null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "1.2.3", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "NewTSL00", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "UNDEFINED",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "MVEL",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "JAVA",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "JYTHON",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", "JAVASCRIPT",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", "JRUBY",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updatePolicyStateTaskSelectionLogic(null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState99", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy2", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy1", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "NonExistantState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "",
+ "Some Other Policy Logic");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "MVEL",
+ "Some Other Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyPolicy012", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", null,
+ "Some Other Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyPolicy015", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyPolicy014", "0.1.5", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listPolicyStateTaskSelectionLogic(null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("zooby", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("zooby", null, "looby");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("zooby", null, "TestState1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "looby");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.2", "TestState1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+
+ result = apexModel.deletePolicyStateTaskSelectionLogic(null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("zooby", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("zooby", null, "looby");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("zooby", null, "TestState1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", null, "looby");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.2", "TestState1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", null,
+ "Some Other Policy Logic");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", "JRUBY",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createPolicyStateOutput(null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", null, "SomeState", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", null, "SomeState", "SomeOutput", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "1.2.3", "TestState1", "SomeOutput", null, null,
+ null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", null, null,
+ null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput",
+ "SomeDummyEvent", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", "inEvent",
+ "1.2.3", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", "inEvent",
+ "0.0.1", "SomeDummyNextState");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", "inEvent",
+ "0.0.1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+ "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+ "0.0.1", "TestState2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+ "0.0.1", "TestState2");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "AnotherOtherOutput",
+ "outEvent0", "0.0.1", "TestState3");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "YetAnotherOtherOutput",
+ "outEvent0", "0.0.1", "TestState3");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listPolicyStateOutput(null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.2", "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "SomeState", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "YetAnotherOtherOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "YetAnotherOtherOutput");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState3", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deletePolicyStateOutput(null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.2", "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, "SomeState", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.1", "TestState3", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.1", "TestState3", "DummyOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState1", null);
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, "TestState1", "SomeOutput");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState2", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, "TestState2", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState2", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", "inEvent",
+ "0.0.1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+ "0.0.1", "TestState1");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+ "0.0.1", "TestState2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "AnotherOtherOutput",
+ "outEvent0", "0.0.1", "TestState3");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "YetAnotherOtherOutput",
+ "outEvent0", "0.0.1", "TestState3");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createPolicyStateFinalizerLogic(null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "SomeState", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "SomeState", "SFLName01", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "1.2.3", "TestState1", "SFLName01", null,
+ null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName01", null,
+ null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName01",
+ "NewTSL00", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName02",
+ "UNDEFINED", "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName03", "MVEL",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName03", "MVEL",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName04", "JAVA",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName05", "JYTHON",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06",
+ "JAVASCRIPT", "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName07", "JRUBY",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updatePolicyStateFinalizerLogic(null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, "TestState99", "SomeSFLName", null,
+ null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy2", null, "TestState1", "SomeSFLName", null,
+ null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy1", "0.0.2", "TestState1", "SomeSFLName", null,
+ null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "NonEistantSFL", null,
+ null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06", null,
+ null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06", "",
+ "Some Other Policy Logic");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06", "MVEL",
+ "Some Other Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyPolicy012", null, "TestState1", "SFLName06", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06", null,
+ "Some Other Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyPolicy015", null, "TestState1", "SFLName06", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updatePolicyStateFinalizerLogic("MyPolicy014", "0.1.5", "TestState1", "SFLName06", null,
+ null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listPolicyStateFinalizerLogic(null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", "0.0.2", "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "SomeState", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("zooby", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("zooby", null, "looby", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("zooby", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "looby", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", "0.0.2", "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(6, result.getMessages().size());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+
+ result = apexModel.deletePolicyStateFinalizerLogic(null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.2", "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", null, "SomeState", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("zooby", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("zooby", null, "looby", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("zooby", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", null, "looby", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.2", "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(5, result.getMessages().size());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName02");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName02");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName02");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+ result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName02",
+ "UNDEFINED", "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName03", "MVEL",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName04", "JAVA",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName05", "JYTHON",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06",
+ "JAVASCRIPT", "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName07", "JRUBY",
+ "Some Policy Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createTask("TestTask0", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTask("TestTask1", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTask("TestTask2", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTask("TestTask3", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTask("TestTask4", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createPolicyStateTaskRef(null, null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, null, null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "SomeState", null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "SomeState", null, null, null, null,
+ "DummyOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "1.2.3", "SomeState", null, null, null, null,
+ "DummyOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("AnyOldPolicy", "1.2.3", "SomeState", null, null, null, null,
+ "DummyOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", null,
+ null, null, "DummyOutput");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName",
+ "SomeTask", "Zooby|", null, "DummyOutput");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName",
+ "SomeTask", "0.0.1", null, "DummyOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", "task",
+ "0.0.1", null, "DummyOutput");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", "task",
+ "0.0.1", "Some Policy Logic", "DummyOutput");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", "task",
+ "0.0.1", "DIRECT", "DummyOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", "task",
+ "0.0.1", "LOGIC", "DummyOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName", "task",
+ "0.0.1", "DIRECT", "SFLName07");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName", "task",
+ "0.0.1", "LOGIC", "SomeOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName", "task",
+ "0.0.1", "DIRECT", "SomeOutput");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+ "NonExistantTask", "0.0.1", "DIRECT", "SomeOutput");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName", "task",
+ "0.0.1", "LOGIC", "SFLName07");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+ "TestTask0", "0.0.1", "LOGIC", "SFLName07");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+ "TestTask1", "0.0.1", "DIRECT", "SomeOtherOutput");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+ "TestTask2", "0.0.1", "LOGIC", "SFLName07");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+ "TestTask3", "0.0.1", "DIRECT", "SomeOtherOutput");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, "TestTask4", "0.0.1",
+ "LOGIC", "SFLName07");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, "TestTask4", "0.0.1",
+ "LOGIC", "SFLName07");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "TestState1", "TestTask4", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+ "TestTask4", "0.0.1", "FUNKY", "SFLName07");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+ "TestTask4", "0.0.1", "UNDEFINED", "SFLName07");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+ "TestTask4", "0.0.1", "LOGIC", "SFLName07");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, "TestTask0", "0.0.1",
+ "LOGIC", "SFLName07");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ result = apexModel.listPolicyStateTaskRef(null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", "0.0.1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", "0.0.1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("zooby", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("zooby", null, "looby", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("zooby", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "looby", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(12, result.getMessages().size());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeOldTask", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "task", "1.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "task", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.deletePolicyStateTaskRef(null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("zooby", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("zooby", null, "looby", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("zooby", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "looby", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "ADummyTask", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "task", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(12, result.getMessages().size());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "TestState1", "TestTask0", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(10, result.getMessages().size());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "TestState1", "TestTask2", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(8, result.getMessages().size());
+ result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(4, result.getMessages().size());
+ result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createPolicyStateContextRef(null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", null, "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", null, "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "1.2.3", "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("AnyOldPolicy", "1.2.3", "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTask", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTask", "Zooby|");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTask", "0.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "task", "0.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyPolicy123", null, null, "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyPolicy123", null, "TestState1", "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "4.5.6", "TestState1", "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.1.4", "TestState1", "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", null, "TestState1", "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ result = apexModel.listPolicyStateContextRef(null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateContextRef("zooby", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateContextRef("zooby", null, "looby", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("zooby", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, "looby", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "AContextMap04", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "1.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deletePolicyStateContextRef(null, null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "SomeState", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("zooby", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("zooby", null, "looby", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("zooby", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "looby", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "ADummyContextMap", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "AContextMap04", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", "contextAlbum0", "0.1.5");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", "contextAlbum1", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, "TestState1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deletePolicy(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(3, result.getMessages().size());
+
+ result = apexModel.listPolicy(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(0, result.getMessages().size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiTaskTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiTaskTest.java
new file mode 100644
index 000000000..15e53f925
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexEditorApiTaskTest.java
@@ -0,0 +1,376 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.modelapi.impl.ApexModelImpl;
+
+/**
+ * Test tasks for API tests.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexEditorApiTaskTest {
+ @Test
+ public void testTaskCrud() {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = apexModel.validateTask(null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.validateTask("%%%$£", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.createTask("@^^$^^$", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+ "A description of 002");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+ "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+ "A description of 002");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createTask("MyTask012", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTask("MyTask012", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.listTask(null, null);
+ result = apexModel.createTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+ "A description of 002");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createTask("MyTask012", "0.1.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+ "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.deleteTask("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+ "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.validateTask(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updateTask("@$$$£", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updateTask("MyTask002", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTask("MyTask002", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+ "A description of 002");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTask("MyTask012", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTask("MyTask012", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTask("MyTask012", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTask("MyTask015", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateTask("MyTask014", "0.1.5", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listTask("£@£@@£@£", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listTask(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTask("MyTask012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTask("MyTask012", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTask("MyTask012", "0.2.5");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listTask("MyTask014", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteTask("@£££@", "0.1.1");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deleteTask("MyTask012", "0.1.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deleteTask("MyTask012oooo", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listTask("MyTask012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.deleteTask("MyTask012", "0.1.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listTask("MyTask012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+
+ result = apexModel.deleteTask("MyTask012", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.listTask("MyTask012", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.updateTaskLogic("MyTask002", null, "NewLogic00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createTaskLogic("MyTask123", null, "NewLogic00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", "4.5.6", "NewLogic00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", "0.1.4", "NewLogic00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", "0.0.2", "NewLogic00", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", "0.0.2", "UNDEFINED", "Some Task Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", "0.0.2", "MVEL", "Some Task Logic");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", "0.0.2", "JAVA", "Some Task Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", "0.0.2", "JYTHON", "Some Task Logic");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", null, "JAVASCRIPT", "Some Task Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskLogic("MyTask002", null, "JRUBY", "Some Task Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.updateTaskLogic("MyTask002", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTaskLogic("MyTask002", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateTaskLogic("MyTask002", "0.0.2", "", "Some Other Task Logic");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.updateTaskLogic("MyTask002", "0.0.2", "MVEL", "Some Other Task Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTaskLogic("MyTask012", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateTaskLogic("MyTask002", null, null, "Some Other Task Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTaskLogic("MyTask002", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.updateTaskLogic("MyTask015", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.updateTaskLogic("MyTask014", "0.1.5", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.listTaskLogic("MyTask002", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskLogic("MyTask002", "0.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskLogic(null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.deleteTaskLogic("@£@£@£", "0.0.2");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deleteTaskLogic("NonExistantTask", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ assertEquals(1, apexModel.listTaskLogic("MyTask002", null).getMessages().size());
+ result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskLogic("MyTask002", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(1, apexModel.listTaskLogic("MyTask002", null).getMessages().size());
+ result = apexModel.createTaskLogic("MyTask002", null, "JRUBY", "Some Task Logic");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskLogic("MyTask002", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createTaskField("MyTask002", "0.0.2", "NewField00", "eventContextItem0", null, false);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(ApexModelImpl.FIELDS_DEPRECATED_WARN_MSG, result.getMessage().trim());
+ result = apexModel.handleTaskField("MyTask002", "0.0.2", "NewField01");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(ApexModelImpl.FIELDS_DEPRECATED_WARN_MSG, result.getMessage().trim());
+
+ result = apexModel.createTaskParameter("MyTask123", null, "NewPar00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createTaskParameter("MyTask002", "4.5.6", "NewPar00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createTaskParameter("MyTask002", "0.1.4", "NewPar00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar00", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar00", "eventContextItem0");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar00", "eventContextItem0");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar01", "eventContextItem0");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar02", "eventContextItem0");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar02", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar03", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createTaskParameter("MyTask002", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createTaskParameter("MyTask002", null, null, "Default value");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.listTaskParameter("@£$%", null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listTaskParameter("MyTask002", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskParameter("MyTask002", "0.0.3", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listTaskParameter("MyTask002", "0.0.2", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskParameter("MyTask002", "0.0.2", "NewPar01");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskParameter("MyTask002", "0.0.2", "NewPar02");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskParameter("MyTask002", "0.0.2", "NewPar04");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteTaskParameter("@£$%", "0.0.2", "NewPar04");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deleteTaskParameter("NonExistantTask", "0.0.2", "NewPar04");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(3, apexModel.listTaskParameter("MyTask002", null, null).getMessages().size());
+ result = apexModel.deleteTaskParameter("MyTask002", "0.0.2", "NewPar04");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(3, apexModel.listTaskParameter("MyTask002", null, null).getMessages().size());
+ result = apexModel.deleteTaskParameter("MyTask002", null, "NewPar02");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, apexModel.listTaskParameter("MyTask002", null, null).getMessages().size());
+ result = apexModel.deleteTaskParameter("MyTask002", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.listTaskParameter("MyTask002", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deleteTaskParameter("MyTask002", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createTaskContextRef("@£$$", null, "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask123", null, "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask123", null, "AContextMap00", "0.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask123", null, "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", "4.5.6", "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", "0.1.4", "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "AContextMap00", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum2", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum1", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = apexModel.createTaskContextRef("MyTask002", null, "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ result = apexModel.listTaskContextRef("@£$%", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.listTaskContextRef("MyTask002", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.2", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "AContextMap04", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum1", "0.0.1");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum1", "0.0.2");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteTaskContextRef("@£$%", "0.0.2", "AContextMap04", null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ result = apexModel.deleteTaskContextRef("NonExistantTask", "0.0.2", "AContextMap04", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ assertEquals(2, apexModel.listTaskContextRef("MyTask002", null, null, null).getMessages().size());
+ result = apexModel.deleteTaskContextRef("MyTask002", "0.0.2", "AContextMap04", null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deleteTaskContextRef("MyTask002", null, "contextAlbum0", "0.0.3");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deleteTaskContextRef("MyTask002", null, "contextAlbum0", "0.1.5");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+ result = apexModel.deleteTaskContextRef("MyTask002", null, "contextAlbum0", null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.deleteTaskContextRef("MyTask002", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(1, result.getMessages().size());
+ result = apexModel.listTaskContextRef("MyTask002", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = apexModel.deleteTask(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(2, result.getMessages().size());
+
+ result = apexModel.listTask(null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertEquals(0, result.getMessages().size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexModelApiTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexModelApiTest.java
new file mode 100644
index 000000000..f28d0e634
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ApexModelApiTest.java
@@ -0,0 +1,208 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.modelapi;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.UUID;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.modelapi.impl.ApexModelImpl;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+
+/**
+ * Test the apex model API.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexModelApiTest {
+ private Connection connection;
+
+ @Before
+ public void setup() throws Exception {
+ // Hold the h2 database up for entire tests
+ connection = DriverManager.getConnection("jdbc:h2:mem:testdb");
+ }
+
+ @After
+ public void teardown() throws Exception {
+ // Close the h2 database after tests
+ connection.close();
+ }
+
+ @Test
+ public void testApexModelLoadFromFile() {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = apexModel.loadFromFile("src/main/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.junk");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ assertEquals("Unable to unmarshal Apex concept", result.getMessages().get(0).trim());
+ }
+
+ @Test
+ public void testApexModelSaveToFile() throws IOException {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ final File tempJsonModelFile = File.createTempFile("ApexModelTest", ".json");
+ result = apexModel.saveToFile(tempJsonModelFile.getPath());
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ final ApexModel jsonApexModel = new ApexModelFactory().createApexModel(null);
+ result = jsonApexModel.loadFromFile(tempJsonModelFile.getPath());
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ tempJsonModelFile.delete();
+
+ final File tempModelFile = File.createTempFile("ApexModelTest", ".json");
+ result = apexModel.saveToFile(tempModelFile.getPath());
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ final ApexModel testApexModel = new ApexModelFactory().createApexModel(null);
+ result = testApexModel.loadFromFile(tempModelFile.getPath());
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ tempModelFile.delete();
+ }
+
+ @Test
+ public void testApexModelUrl() throws IOException {
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ assertThatThrownBy(() -> apexModel.readFromUrl(null)).isInstanceOf(IllegalArgumentException.class);
+ assertThatThrownBy(() -> apexModel.writeToUrl(null)).isInstanceOf(IllegalArgumentException.class);
+ ApexApiResult result = null;
+ result = apexModel.readFromUrl("zooby/looby");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.writeToUrl("zooby/looby");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.readFromUrl("zooby://zooby/looby");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.writeToUrl("zooby://zooby/looby");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ final File tempJsonModelFile = File.createTempFile("ApexModelTest", "json");
+
+ result = apexModel.saveToFile(tempJsonModelFile.getPath());
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ final String tempFileUrlString = tempJsonModelFile.toURI().toString();
+ result = apexModel.readFromUrl(tempFileUrlString);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.writeToUrl(tempFileUrlString);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ assertEquals("protocol doesn't support output", result.getMessages().get(0));
+
+ tempJsonModelFile.delete();
+ }
+
+ @Test
+ public void testApexModelMisc() throws IOException {
+ final ApexModelImpl apexModelImpl = (ApexModelImpl) new ApexModelFactory().createApexModel(null);
+
+ ApexApiResult result = null;
+
+ result = apexModelImpl.getModelKey();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.listModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.createModel("ModelName", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.updateModel("ModelName", "0.0.1", UUID.randomUUID().toString(), "Model Description");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ apexModelImpl.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ final String modelString = TextFileUtils.getTextFileAsString("src/test/resources/models/PolicyModel.json");
+ result = apexModelImpl.loadFromString(modelString);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ final File tempFile = File.createTempFile("ApexModel", "json");
+ tempFile.deleteOnExit();
+ TextFileUtils.putStringAsFile(modelString, tempFile);
+
+ apexModelImpl.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.loadFromFile(tempFile.getPath());
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.analyse();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.validate();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.compare(tempFile.getPath(), true, true);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.compareWithString(modelString, true, true);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.split("policy");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.split(tempFile.getPath(), "policy");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.merge(tempFile.getPath(), true);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModelImpl.mergeWithString(modelString, true);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ assertNotEquals(0, apexModelImpl.hashCode());
+ assertNotNull(apexModelImpl.getCopy());
+ assertNotNull(apexModelImpl.build());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ModelFacadeTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ModelFacadeTest.java
new file mode 100644
index 000000000..d3b32b923
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ModelFacadeTest.java
@@ -0,0 +1,99 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.modelapi;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Properties;
+import java.util.UUID;
+import org.junit.Test;
+import org.onap.policy.apex.model.modelapi.impl.ModelFacade;
+
+public class ModelFacadeTest {
+
+ @Test
+ public void testModelFacade() {
+ assertThatThrownBy(() -> new ModelFacade(null, null))
+ .hasMessage("apexModel may not be null");
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ assertThatThrownBy(() -> new ModelFacade(apexModel, null))
+ .hasMessage("apexProperties may not be null");
+ final Properties modelProperties = new Properties();
+ final ModelFacade mf = new ModelFacade(apexModel, modelProperties);
+
+ ApexApiResult result = mf.createModel(null, null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mf.createModel("ModelName", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mf.createModel("ModelName", "0.0.1", null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ modelProperties.setProperty("DEFAULT_CONCEPT_VERSION", "");
+ result = mf.createModel("ModelName", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ modelProperties.setProperty("DEFAULT_CONCEPT_VERSION", "£$£$£$");
+ result = mf.createModel("ModelName", null, null, null);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ modelProperties.setProperty("DEFAULT_CONCEPT_VERSION", "0.0.1");
+ result = mf.createModel("ModelName", null, null, null);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+ result = mf.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = mf.createModel("ModelName", null, null, null);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mf.updateModel("ModelName", null, UUID.randomUUID().toString(), "New Description");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mf.updateModel("ModelName", "0.0.1", UUID.randomUUID().toString(), "New Description");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ modelProperties.remove("DEFAULT_CONCEPT_VERSION");
+ result = mf.updateModel("ModelName", null, UUID.randomUUID().toString(), "New Description");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mf.updateModel(null, null, UUID.randomUUID().toString(), "New Description");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mf.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = mf.updateModel("name", "0.0.1", UUID.randomUUID().toString(), "New Description");
+ assertEquals(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+ result = mf.getModelKey();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mf.listModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mf.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ assertNotNull(mf);
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/ModelHandlerFacadeTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/ModelHandlerFacadeTest.java
new file mode 100644
index 000000000..5bbc95992
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/ModelHandlerFacadeTest.java
@@ -0,0 +1,128 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.modelapi;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import org.junit.Test;
+import org.onap.policy.apex.model.modelapi.impl.ModelHandlerFacade;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+
+/**
+ * Test the model handler facade.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ModelHandlerFacadeTest {
+
+ @Test
+ public void testModelHandlerFacade() throws IOException {
+ assertThatThrownBy(() -> new ModelHandlerFacade(null, null))
+ .hasMessage("apexModel may not be null");
+ final ApexModel apexModel = new ApexModelFactory().createApexModel(null);
+
+ assertThatThrownBy(() -> new ModelHandlerFacade(apexModel, null))
+ .hasMessage("apexProperties may not be null");
+ final Properties modelProperties = new Properties();
+ final ModelHandlerFacade mhf = new ModelHandlerFacade(apexModel, modelProperties);
+ assertNotNull(mhf);
+
+ ApexApiResult result = mhf.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mhf.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ final String modelString = TextFileUtils.getTextFileAsString("src/test/resources/models/PolicyModel.json");
+
+ result = apexModel.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mhf.loadFromString(modelString);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mhf.loadFromString(modelString);
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ result = apexModel.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mhf.readFromUrl("blah://somewhere/over/the/rainbow");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mhf.loadFromString(modelString);
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mhf.readFromUrl("http://somewhere/over/the/rainbow");
+ assertEquals(ApexApiResult.Result.CONCEPT_EXISTS, result.getResult());
+
+ final File tempFile = File.createTempFile("ApexModel", "json");
+ tempFile.deleteOnExit();
+
+ result = mhf.writeToUrl("File:///" + tempFile.getCanonicalPath());
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mhf.validate();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = apexModel.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = mhf.validate();
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mhf.compare("src/test/resources/models/NonExistant.json", true, true);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mhf.compareWithString("zooby", true, true);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mhf.split("FailSplit", "NonExistantPolicy");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mhf.split("NonExistantPolicy");
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mhf.merge("src/test/resources/models/NonExistant.json", false);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = mhf.merge("src/test/resources/models/PolicyModel.json", false);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = mhf.loadFromFile("src/test/resources/models/PolicyModel.json");
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+
+ result = mhf.mergeWithString("@£@$@£", true);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+
+ result = apexModel.deleteModel();
+ assertEquals(ApexApiResult.Result.SUCCESS, result.getResult());
+ result = mhf.mergeWithString(modelString, false);
+ assertEquals(ApexApiResult.Result.FAILED, result.getResult());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/modelapi/RealModelTest.java b/model/src/test/java/org/onap/policy/apex/model/modelapi/RealModelTest.java
new file mode 100644
index 000000000..2a29f5297
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/modelapi/RealModelTest.java
@@ -0,0 +1,46 @@
+/*-
+ * ============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.onap.policy.apex.model.modelapi;
+
+import static org.junit.Assert.assertTrue;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.util.Map;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelCustomGsonMapAdapter;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+
+public class RealModelTest {
+ @Test
+ public void testRealModel() throws Exception {
+
+ final String modelString = TextFileUtils.getTextFileAsString("src/test/resources/models/PolicyModel.json");
+
+ AxPolicyModel policyModel = new ApexModelReader<AxPolicyModel>(AxPolicyModel.class).read(modelString);
+
+ AxValidationResult result = new AxValidationResult();
+ assertTrue(policyModel.validate(result).isValid());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/DummyLogicReader.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/DummyLogicReader.java
new file mode 100644
index 000000000..007288343
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/DummyLogicReader.java
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.policymodel.concepts;
+
+public class DummyLogicReader implements AxLogicReader {
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getLogicPackage() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxLogicReader setLogicPackage(final String logicPackage) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getDefaultLogic() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxLogicReader setDefaultLogic(final String defaultLogic) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String readLogic(final AxLogic axLogic) {
+ return "Dummy Logic";
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/ExceptionsTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/ExceptionsTest.java
new file mode 100644
index 000000000..0afb48b3c
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/ExceptionsTest.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import org.junit.Test;
+
+/**
+ * Test model exceptions.
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ExceptionsTest {
+
+ @Test
+ public void test() {
+ assertNotNull(new PolicyException("Message"));
+ assertNotNull(new PolicyException("Message", new IOException()));
+
+ final PolicyException ae = new PolicyException("Message", new IOException("IO exception message"));
+ assertEquals("Message\ncaused by: Message\ncaused by: IO exception message", ae.getCascadedMessage());
+
+ assertNotNull(new PolicyRuntimeException("Message"));
+ assertNotNull(new PolicyRuntimeException("Message", new IOException()));
+
+ final PolicyRuntimeException re =
+ new PolicyRuntimeException("Runtime Message", new IOException("IO runtime exception message"));
+ assertEquals("Runtime Message\ncaused by: Runtime Message\ncaused by: IO runtime exception message",
+ re.getCascadedMessage());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/LogicTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/LogicTest.java
new file mode 100644
index 000000000..fbfc7c4a0
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/LogicTest.java
@@ -0,0 +1,161 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Test apex logic.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class LogicTest {
+
+ @Test
+ public void testLogic() {
+ final DummyLogicReader logicReader = new DummyLogicReader();
+
+ assertNotNull(new AxLogic());
+ assertNotNull(new AxLogic(new AxReferenceKey()));
+ assertNotNull(new AxLogic(new AxReferenceKey(), "LogicFlavour", "Logic"));
+ assertNotNull(new AxLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", "Logic"));
+ assertNotNull(new AxLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+
+ assertNotNull(new AxTaskLogic());
+ assertNotNull(new AxTaskLogic(new AxReferenceKey()));
+ assertNotNull(new AxTaskLogic(new AxReferenceKey(), "LogicFlavour", "Logic"));
+ assertNotNull(new AxTaskLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxTaskLogic(new AxLogic()));
+ assertNotNull(new AxTaskLogic(new AxArtifactKey(), "LogicName", "LogicFlavour", logicReader));
+ assertNotNull(new AxTaskLogic(new AxArtifactKey(), "LogicName", "LogicFlavour", "Logic"));
+ assertNotNull(new AxTaskLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+
+ assertNotNull(new AxTaskSelectionLogic());
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey()));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicFlavour", "Logic"));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", "Logic"));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxTaskSelectionLogic(new AxLogic()));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", logicReader));
+
+ assertNotNull(new AxStateFinalizerLogic());
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey()));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicFlavour", "Logic"));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", "Logic"));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxStateFinalizerLogic(new AxLogic()));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", logicReader));
+
+ final AxLogic logic = new AxLogic();
+
+ final AxReferenceKey logicKey = new AxReferenceKey("LogicParentName", "0.0.1", "PLN", "LN");
+ logic.setKey(logicKey);
+ assertEquals("LogicParentName:0.0.1:PLN:LN", logic.getKey().getId());
+ assertEquals("LogicParentName:0.0.1:PLN:LN", logic.getKeys().get(0).getId());
+
+ logic.setLogicFlavour("LogicFlavour");
+ assertEquals("LogicFlavour", logic.getLogicFlavour());
+
+ logic.setLogic("Logic");
+ assertEquals("Logic", logic.getLogic());
+
+ AxValidationResult result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ logic.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ logic.setKey(logicKey);
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ assertThatThrownBy(() -> logic.setLogicFlavour(null))
+ .hasMessageContaining("parameter \"logicFlavour\" is null");
+ assertThatThrownBy(() -> logic.setLogicFlavour(""))
+ .hasMessage("parameter \"logicFlavour\": value \"\", "
+ + "does not match regular expression \"[A-Za-z0-9\\-_]+\"");
+ logic.setLogicFlavour(AxLogic.LOGIC_FLAVOUR_UNDEFINED);
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ logic.setLogicFlavour("LogicFlavour");
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ assertThatThrownBy(() -> logic.setLogic(null)).hasMessage("logic may not be null");
+ logic.setLogic("");
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ logic.setLogic("Logic");
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ logic.clean();
+
+ final AxLogic clonedLogic = new AxLogic(logic);
+ assertEquals("AxLogic:(key=AxReferenceKey:(parentKeyName=LogicParentName,parentKeyVersion=0.0.1,"
+ + "parentLocalName=PLN,localName=LN),logicFlavour=LogicFlavour,logic=Logic)",
+ clonedLogic.toString());
+
+ assertNotEquals(0, logic.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(logic, logic); // NOSONAR
+ assertEquals(logic, clonedLogic);
+ assertNotNull(logic);
+ assertNotEquals(logic, (Object) "Hello");
+ assertNotEquals(logic, new AxLogic(AxReferenceKey.getNullKey(), "LogicFlavour", "Logic"));
+ assertNotEquals(logic, new AxLogic(logicKey, "AnotherLogicFlavour", "Logic"));
+ assertNotEquals(logic, new AxLogic(logicKey, "LogicFlavour", "AnotherLogic"));
+ assertEquals(logic, new AxLogic(logicKey, "LogicFlavour", "Logic"));
+
+ assertEquals(0, logic.compareTo(logic));
+ assertEquals(0, logic.compareTo(clonedLogic));
+ assertNotEquals(0, logic.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, logic.compareTo(null));
+ assertNotEquals(0, logic.compareTo(new AxLogic(AxReferenceKey.getNullKey(), "LogicFlavour", "Logic")));
+ assertNotEquals(0, logic.compareTo(new AxLogic(logicKey, "AnotherLogicFlavour", "Logic")));
+ assertNotEquals(0, logic.compareTo(new AxLogic(logicKey, "LogicFlavour", "AnotherLogic")));
+ assertEquals(0, logic.compareTo(new AxLogic(logicKey, "LogicFlavour", "Logic")));
+
+ assertNotNull(logic.getKeys());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/PoliciesTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/PoliciesTest.java
new file mode 100644
index 000000000..526f5a628
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/PoliciesTest.java
@@ -0,0 +1,391 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Map;
+import java.util.TreeMap;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.policymodel.handling.SupportApexPolicyModelCreator;
+
+/**
+ * Test apex policies.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PoliciesTest {
+
+ @Test
+ public void testPolicies() {
+ final TreeMap<String, AxState> stateMap = new TreeMap<>();
+ final TreeMap<String, AxState> stateMapEmpty = new TreeMap<>();
+
+ assertNotNull(new AxPolicy());
+ assertNotNull(new AxPolicy(new AxArtifactKey()));
+ assertNotNull(new AxPolicy(new AxArtifactKey(), "PolicyTemplate", stateMapEmpty, "FirstState"));
+
+ final AxPolicy policy = new AxPolicy();
+
+ final AxArtifactKey policyKey = new AxArtifactKey("PolicyName", "0.0.1");
+
+ final AxState firstState = new AxState(new AxReferenceKey(policy.getKey(), "FirstState"));
+ final AxState badState = new AxState(new AxReferenceKey(policy.getKey(), "BadState"));
+ final AxStateOutput badStateOutput = new AxStateOutput(badState.getKey(), AxArtifactKey.getNullKey(),
+ new AxReferenceKey(policyKey, "BadNextState"));
+ badState.getStateOutputs().put(badStateOutput.getKey().getLocalName(), badStateOutput);
+ stateMap.put(firstState.getKey().getLocalName(), firstState);
+
+ assertThatThrownBy(() -> policy.setKey(null))
+ .hasMessage("key may not be null");
+ policy.setKey(policyKey);
+ assertEquals("PolicyName:0.0.1", policy.getKey().getId());
+ assertEquals("PolicyName:0.0.1", policy.getKeys().get(0).getId());
+
+ assertThatThrownBy(() -> policy.setTemplate(null))
+ .hasMessage("template may not be null");
+ policy.setTemplate("PolicyTemplate");
+ assertEquals("PolicyTemplate", policy.getTemplate());
+
+ assertThatThrownBy(() -> policy.setStateMap(null))
+ .hasMessage("stateMap may not be null");
+ policy.setStateMap(stateMap);
+ assertEquals(stateMap, policy.getStateMap());
+
+ assertThatThrownBy(() -> policy.setFirstState(null))
+ .hasMessage("firstState may not be null");
+ policy.setFirstState("FirstState");
+ assertEquals("FirstState", policy.getFirstState());
+
+ assertEquals("PolicyName:0.0.1", policy.getKeys().get(0).getId());
+
+ final AxPolicy policyPN = new SupportApexPolicyModelCreator().getModel().getPolicies().get("policy");
+
+ AxValidationResult result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxArtifactKey savedPolicyKey = policyPN.getKey();
+ policyPN.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policyPN.setKey(savedPolicyKey);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final String savedTemplate = policyPN.getTemplate();
+ policyPN.setTemplate("");
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ policyPN.setTemplate(savedTemplate);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final Map<String, AxState> savedStateMap = policyPN.getStateMap();
+
+ policyPN.setStateMap(stateMapEmpty);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policyPN.setStateMap(savedStateMap);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ savedStateMap.put(AxKey.NULL_KEY_NAME, firstState);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ savedStateMap.remove(AxKey.NULL_KEY_NAME);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ savedStateMap.put("NullState", null);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ savedStateMap.remove("NullState");
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ savedStateMap.put("BadStateKey", firstState);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ savedStateMap.remove("BadStateKey");
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ savedStateMap.put(badState.getKey().getLocalName(), badState);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ savedStateMap.remove(badState.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final String savedFirstState = policyPN.getFirstState();
+
+ policyPN.setFirstState("");
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policyPN.setFirstState(savedFirstState);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policyPN.setFirstState("NonExistantFirstState");
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policyPN.setFirstState(savedFirstState);
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxState clonedState = new AxState(policyPN.getStateMap().get("state"));
+ clonedState.getKey().setLocalName("ClonedState");
+
+ savedStateMap.put(clonedState.getKey().getLocalName(), clonedState);
+ policyPN.buildReferences();
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.WARNING, result.getValidationResult());
+
+ savedStateMap.remove(clonedState.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = policyPN.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policyPN.clean();
+
+ final AxPolicy clonedPolicy = new AxPolicy(policyPN);
+ assertEquals("AxPolicy:(key=AxArtifactKey:(name=policy,version=0.0.1),template=FREEFORM,sta",
+ clonedPolicy.toString().substring(0, 77));
+
+ assertNotEquals(0, policyPN.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(policyPN, policyPN); // NOSONAR
+ assertEquals(policyPN, clonedPolicy);
+ assertNotNull(policyPN);
+
+ Object helloObj = "Hello";
+ assertNotEquals(policyPN, helloObj);
+ assertNotEquals(policyPN,
+ new AxPolicy(AxArtifactKey.getNullKey(), savedTemplate, savedStateMap, savedFirstState));
+ assertNotEquals(policyPN, new AxPolicy(savedPolicyKey, "SomeTemplate", savedStateMap, savedFirstState));
+ assertNotEquals(policyPN, new AxPolicy(savedPolicyKey, savedTemplate, stateMapEmpty, savedFirstState));
+ assertNotEquals(policyPN, new AxPolicy(savedPolicyKey, savedTemplate, savedStateMap, "SomeFirstState"));
+ assertEquals(policyPN, new AxPolicy(savedPolicyKey, savedTemplate, savedStateMap, savedFirstState));
+
+ assertEquals(0, policyPN.compareTo(policyPN));
+ assertEquals(0, policyPN.compareTo(clonedPolicy));
+ assertNotEquals(0, policyPN.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, policyPN.compareTo(null));
+ assertNotEquals(0, policyPN.compareTo(
+ new AxPolicy(AxArtifactKey.getNullKey(), savedTemplate, savedStateMap, savedFirstState)));
+ assertNotEquals(0, policyPN.compareTo(new AxPolicy(savedPolicyKey,
+ "SomeTemplate", savedStateMap, savedFirstState)));
+ assertNotEquals(0, policyPN.compareTo(new AxPolicy(savedPolicyKey, savedTemplate,
+ stateMapEmpty, savedFirstState)));
+ assertNotEquals(0, policyPN.compareTo(new AxPolicy(savedPolicyKey, savedTemplate,
+ savedStateMap, "SomeFirstState")));
+ assertEquals(0, policyPN.compareTo(new AxPolicy(savedPolicyKey, savedTemplate,
+ savedStateMap, savedFirstState)));
+
+ assertNotNull(policyPN.getKeys());
+
+ final AxPolicies policies = new AxPolicies();
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ // Invalid, no events in event map
+ policies.setKey(new AxArtifactKey("PoliciesKey", "0.0.1"));
+ assertEquals("PoliciesKey:0.0.1", policies.getKey().getId());
+
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policies.getPolicyMap().put(savedPolicyKey, policyPN);
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policies.getPolicyMap().put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policies.getPolicyMap().remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policies.getPolicyMap().put(new AxArtifactKey("NullValueKey", "0.0.1"), null);
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policies.getPolicyMap().remove(new AxArtifactKey("NullValueKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policies.getPolicyMap().put(new AxArtifactKey("BadEventKey", "0.0.1"), policyPN);
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policies.getPolicyMap().remove(new AxArtifactKey("BadEventKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policies.clean();
+
+ final AxPolicies clonedPolicies = new AxPolicies(policies);
+ assertEquals("AxPolicies:(key=AxArtifactKey:(name=PoliciesKey,version=0.0.",
+ clonedPolicies.toString().substring(0, 60));
+
+ assertNotEquals(0, policies.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(policies, policies); // NOSONAR
+ assertEquals(policies, clonedPolicies);
+ assertNotNull(policies);
+ assertNotEquals(policyPN, helloObj);
+ assertNotEquals(policies, new AxPolicies(new AxArtifactKey()));
+
+ assertEquals(0, policies.compareTo(policies));
+ assertEquals(0, policies.compareTo(clonedPolicies));
+ assertNotEquals(0, policies.compareTo(null));
+ assertNotEquals(0, policies.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, policies.compareTo(new AxPolicies(new AxArtifactKey())));
+
+ clonedPolicies.get(savedPolicyKey).setTemplate("AnotherTemplate");
+ assertNotEquals(0, policies.compareTo(clonedPolicies));
+
+ assertEquals(policies.getKey(), policies.getKeys().get(0));
+
+ assertEquals("policy", policies.get("policy").getKey().getName());
+ assertEquals("policy", policies.get("policy", "0.0.1").getKey().getName());
+ assertEquals(1, policies.getAll("policy", "0.0.1").size());
+ assertEquals(0, policies.getAll("NonExistantPolicy").size());
+
+ AxStateTree stateTree = policy.getStateTree();
+ assertNotNull(stateTree);
+ assertNotNull(stateTree.getReferencedStateList());
+ assertNotNull(stateTree.getReferencedStateSet());
+
+ final AxState secondState = new AxState(policyPN.getStateMap().get("state"));
+ secondState.getKey().setLocalName("SecondState");
+ policyPN.getStateMap().put("SecondState", secondState);
+ policyPN.getStateMap().get("state").getStateOutputs().get("stateOutput0").setNextState(secondState.getKey());
+
+ stateTree = policyPN.getStateTree();
+ assertNotNull(stateTree);
+ assertNotNull(stateTree.getReferencedStateList());
+ assertNotNull(stateTree.getReferencedStateSet());
+ assertNotNull(stateTree.getNextStates());
+
+ policyPN.getStateMap().get("SecondState").getStateOutputs().get("stateOutput0")
+ .setNextState(policyPN.getStateMap().get("state").getKey());
+ assertThatThrownBy(() -> policyPN.getStateTree())
+ .hasMessageContaining("loop detected in state tree for policy policy:0.0.1 state SecondState, "
+ + "next state state referenced more than once");
+ policyPN.getStateMap().get("SecondState").getStateOutputs().get("stateOutput0")
+ .setNextState(AxReferenceKey.getNullKey());
+
+ final AxState thirdState = new AxState(policyPN.getStateMap().get("state"));
+ thirdState.getKey().setLocalName("ThirdState");
+ policyPN.getStateMap().put("ThirdState", thirdState);
+ policyPN.getStateMap().get("SecondState").getStateOutputs().get("stateOutput0")
+ .setNextState(thirdState.getKey());
+ policyPN.getStateMap().get("ThirdState").getStateOutputs().get("stateOutput0")
+ .setNextState(AxReferenceKey.getNullKey());
+
+ stateTree = policyPN.getStateTree();
+
+ final AxStateOutput ssS0Clone = new AxStateOutput(
+ policyPN.getStateMap().get("SecondState").getStateOutputs().get("stateOutput0"));
+ ssS0Clone.getKey().setLocalName("ssS0Clone");
+ policyPN.getStateMap().get("SecondState").getStateOutputs().put("ssS0Clone", ssS0Clone);
+
+ assertThatThrownBy(() -> policyPN.getStateTree())
+ .hasMessageContaining("loop detected in state tree for policy policy:0.0.1 state SecondState, "
+ + "next state ThirdState referenced more than once");
+ policyPN.getStateMap().get("SecondState").getStateOutputs().remove("ssS0Clone");
+
+ policyPN.getStateMap().get("state").getStateOutputs().get("stateOutput0").setNextState(secondState.getKey());
+ secondState.getStateOutputs().get("stateOutput0").setNextState(thirdState.getKey());
+ thirdState.getStateOutputs().get("stateOutput0").setNextState(AxReferenceKey.getNullKey());
+
+ stateTree = policyPN.getStateTree();
+ assertNotNull(stateTree.getState());
+
+ thirdState.getStateOutputs().get("stateOutput0").setNextState(secondState.getKey());
+
+ assertThatThrownBy(() -> policyPN.getStateTree())
+ .hasMessageContaining("loop detected in state tree for policy policy:0.0.1 state ThirdState, "
+ + "next state SecondState referenced more than once");
+ thirdState.getStateOutputs().get("stateOutput0").setNextState(AxReferenceKey.getNullKey());
+
+ stateTree = policyPN.getStateTree();
+
+ final AxStateTree otherStateTree = policyPN.getStateTree();
+ assertEquals(0, stateTree.compareTo(otherStateTree));
+
+ for (final AxStateTree childStateTree : stateTree.getNextStates()) {
+ assertNotEquals(0, stateTree.compareTo(childStateTree));
+ }
+
+ otherStateTree.getNextStates().clear();
+ assertNotEquals(0, stateTree.compareTo(otherStateTree));
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/PolicyModelTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/PolicyModelTest.java
new file mode 100644
index 000000000..b699b5d48
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/PolicyModelTest.java
@@ -0,0 +1,312 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.policymodel.handling.SupportApexPolicyModelCreator;
+
+/**
+ * Test policy models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyModelTest {
+
+ @Test
+ public void testPolicyModel() {
+ assertNotNull(new AxPolicyModel());
+ assertNotNull(new AxPolicyModel(new AxArtifactKey()));
+ assertNotNull(new AxPolicyModel(new AxArtifactKey(), new AxContextSchemas(), new AxKeyInformation(),
+ new AxEvents(), new AxContextAlbums(), new AxTasks(), new AxPolicies()));
+
+ final AxArtifactKey modelKey = new AxArtifactKey("ModelKey", "0.0.1");
+ final AxArtifactKey schemasKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxArtifactKey eventsKey = new AxArtifactKey("EventsKey", "0.0.1");
+ final AxArtifactKey keyInfoKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxArtifactKey albumsKey = new AxArtifactKey("AlbumsKey", "0.0.1");
+ final AxArtifactKey tasksKey = new AxArtifactKey("TasksKey", "0.0.1");
+ final AxArtifactKey policiesKey = new AxArtifactKey("PoliciesKey", "0.0.1");
+
+ AxPolicyModel model = new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey));
+
+ model.register();
+
+ assertNotNull(model.getContextModel());
+ assertEquals("ModelKey:0.0.1", model.getKeys().get(0).getId());
+
+ model.clean();
+ assertNotNull(model);
+ assertEquals("AxPolicyModel:(AxPolicyModel:(key=AxArtifactKey:(n", model.toString().substring(0, 50));
+
+ final AxPolicyModel clonedModel = new AxPolicyModel(model);
+
+ assertNotEquals(0, model.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(model, model); // NOSONAR
+ assertEquals(model, clonedModel);
+ assertNotEquals(model, (Object) "Hello");
+ assertNotEquals(model, new AxPolicyModel(new AxArtifactKey()));
+ assertNotEquals(model, new AxPolicyModel(AxArtifactKey.getNullKey(), new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey)));
+ assertNotEquals(model, new AxPolicyModel(modelKey, new AxContextSchemas(), new AxKeyInformation(keyInfoKey),
+ new AxEvents(eventsKey), new AxContextAlbums(albumsKey), new AxTasks(tasksKey),
+ new AxPolicies(policiesKey)));
+ assertNotEquals(model, new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey), new AxKeyInformation(),
+ new AxEvents(eventsKey), new AxContextAlbums(albumsKey), new AxTasks(tasksKey),
+ new AxPolicies(policiesKey)));
+ assertNotEquals(model, new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey)));
+ assertNotEquals(model, new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey)));
+ assertNotEquals(model, new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(), new AxPolicies(policiesKey)));
+ assertNotEquals(model, new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies()));
+ assertEquals(model, new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey)));
+
+ assertEquals(0, model.compareTo(model));
+ assertEquals(0, model.compareTo(clonedModel));
+ assertNotEquals(0, model.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, model.compareTo(new AxPolicyModel(AxArtifactKey.getNullKey(),
+ new AxContextSchemas(schemasKey), new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey),
+ new AxContextAlbums(albumsKey), new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertNotEquals(0, model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertNotEquals(0, model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey),
+ new AxContextAlbums(), new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey),
+ new AxContextAlbums(albumsKey), new AxTasks(), new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey),
+ new AxContextAlbums(albumsKey), new AxTasks(tasksKey), new AxPolicies())));
+ assertEquals(0, model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+
+ model = new SupportApexPolicyModelCreator().getModel();
+
+ AxValidationResult result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxArtifactKey savedPolicyKey = model.getKey();
+ model.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.setKey(savedPolicyKey);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxField badField = new AxField(new AxReferenceKey(model.getEvents().get("inEvent").getKey(), "BadField"),
+ new AxArtifactKey("NonExistantSchema", "0.0.1"));
+ model.getEvents().get("inEvent").getParameterMap().put(badField.getKey().getLocalName(), badField);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getEvents().get("inEvent").getParameterMap().remove(badField.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxContextAlbum badAlbum = new AxContextAlbum(new AxArtifactKey("BadAlbum", "0.0.1"), "SomeScope", true,
+ new AxArtifactKey("NonExistantSchema", "0.0.1"));
+ model.getAlbums().getAlbumsMap().put(badAlbum.getKey(), badAlbum);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getAlbums().getAlbumsMap().remove(badAlbum.getKey());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.getTasks().get("task").getContextAlbumReferences()
+ .add(new AxArtifactKey("NonExistantContextAlbum", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getTasks().get("task").getContextAlbumReferences()
+ .remove(new AxArtifactKey("NonExistantContextAlbum", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").getContextAlbumReferences()
+ .add(new AxArtifactKey("NonExistantContextAlbum", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").getContextAlbumReferences()
+ .remove(new AxArtifactKey("NonExistantContextAlbum", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxArtifactKey savedTrigger = model.getPolicies().get("policy").getStateMap().get("state").getTrigger();
+ model.getPolicies().get("policy").getStateMap().get("state")
+ .setTrigger(new AxArtifactKey("NonExistantEvent", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").setTrigger(savedTrigger);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxArtifactKey savedDefaultTask = model.getPolicies().get("policy").getStateMap().get("state")
+ .getDefaultTask();
+ model.getPolicies().get("policy").getStateMap().get("state")
+ .setDefaultTask(new AxArtifactKey("NonExistantTask", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").setDefaultTask(savedDefaultTask);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // It is OK not to have TSL
+ final AxTaskSelectionLogic savedTaskSelectionLogic = model.getPolicies().get("policy").getStateMap()
+ .get("state").getTaskSelectionLogic();
+ model.getPolicies().get("policy").getStateMap().get("state")
+ .setTaskSelectionLogic(new AxTaskSelectionLogic(AxReferenceKey.getNullKey()));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").setTaskSelectionLogic(savedTaskSelectionLogic);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxStateOutput badStateOutput = new AxStateOutput(
+ new AxReferenceKey(model.getPolicies().get("policy").getStateMap().get("state").getKey(),
+ "BadSO"),
+ new AxArtifactKey("NonExistantEvent", "0.0.1"), AxReferenceKey.getNullKey());
+ model.getPolicies().get("policy").getStateMap().get("state").getStateOutputs()
+ .put(badStateOutput.getKey().getLocalName(), badStateOutput);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").getStateOutputs()
+ .remove(badStateOutput.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxStateTaskReference badTaskReference = new AxStateTaskReference(
+ new AxReferenceKey(model.getPolicies().get("policy").getStateMap().get("state").getKey(),
+ "NonExistantTask"),
+ AxStateTaskOutputType.LOGIC, badStateOutput.getKey());
+ model.getPolicies().get("policy").getStateMap().get("state").getTaskReferences()
+ .put(new AxArtifactKey("NonExistantTask", "0.0.1"), badTaskReference);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ badTaskReference.setStateTaskOutputType(AxStateTaskOutputType.DIRECT);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").getTaskReferences()
+ .remove(new AxArtifactKey("NonExistantTask", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxStateTaskReference tr = model.getPolicies().get("policy").getStateMap().get("state").getTaskReferences()
+ .get(new AxArtifactKey("task", "0.0.1"));
+
+ final String savedStateOutputName = tr.getOutput().getLocalName();
+ tr.getOutput().setLocalName("NonExistantOutput");
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tr.getOutput().setLocalName(savedStateOutputName);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxStateOutput so = model.getPolicies().get("policy").getStateMap().get("state").getStateOutputs()
+ .get(savedStateOutputName);
+
+ final AxArtifactKey savedOutEvent = so.getOutgoingEvent();
+ so.setOutgoingEvent(new AxArtifactKey("NonExistantEvent", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ so.setOutgoingEvent(savedOutEvent);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateOutputTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateOutputTest.java
new file mode 100644
index 000000000..049783a7f
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateOutputTest.java
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Test state outputs.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class StateOutputTest {
+
+ @Test
+ public void testStateOutput() {
+ assertNotNull(new AxStateOutput());
+ assertNotNull(new AxStateOutput(new AxReferenceKey()));
+ assertNotNull(new AxStateOutput(new AxReferenceKey(), new AxReferenceKey(), new AxArtifactKey()));
+ assertNotNull(new AxStateOutput(new AxReferenceKey(), new AxArtifactKey(), new AxReferenceKey()));
+
+ final AxStateOutput so = new AxStateOutput();
+
+ final AxReferenceKey soKey = new AxReferenceKey("SOStateParent", "0.0.1", "SOState", "SOName");
+ final AxReferenceKey nsKey = new AxReferenceKey("SOStateParent", "0.0.1", "NotUsed", "NextStateName");
+ final AxArtifactKey eKey = new AxArtifactKey("EventName", "0.0.1");
+
+ assertThatThrownBy(() -> so.setKey(null))
+ .hasMessage("key is marked non-null but is null");
+ so.setKey(soKey);
+ assertEquals("SOStateParent:0.0.1:SOState:SOName", so.getKey().getId());
+ assertEquals("SOStateParent:0.0.1:SOState:SOName", so.getKeys().get(0).getId());
+
+ assertThatThrownBy(() -> so.setNextState(null))
+ .hasMessage("nextState is marked non-null but is null");
+ so.setNextState(nsKey);
+ assertEquals(nsKey, so.getNextState());
+
+ assertThatThrownBy(() -> so.setOutgoingEvent(null))
+ .hasMessage("outgoingEvent is marked non-null but is null");
+ so.setOutgoingEvent(eKey);
+ assertEquals(eKey, so.getOutgoingEvent());
+
+ AxValidationResult result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ so.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ so.setKey(soKey);
+ result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ so.setOutgoingEvent(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ so.setOutgoingEvent(eKey);
+ result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ so.clean();
+
+ final AxStateOutput clonedPar = new AxStateOutput(so);
+ assertEquals("AxStateOutput:(stateKey=AxReferenceKey:(parentKeyN", clonedPar.toString().substring(0, 50));
+
+ assertNotEquals(0, so.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(so, so); // NOSONAR
+ assertEquals(so, clonedPar);
+ assertNotNull(so);
+ assertNotEquals(so, (Object) "Hello");
+ assertNotEquals(so, new AxStateOutput(AxReferenceKey.getNullKey(), eKey, nsKey));
+ assertNotEquals(so, new AxStateOutput(soKey, new AxArtifactKey(), nsKey));
+ assertNotEquals(so, new AxStateOutput(soKey, eKey, new AxReferenceKey()));
+ assertEquals(so, new AxStateOutput(soKey, eKey, nsKey));
+
+ assertEquals(0, so.compareTo(so));
+ assertEquals(0, so.compareTo(clonedPar));
+ assertNotEquals(0, so.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, so.compareTo(null));
+ assertNotEquals(0, so.compareTo(new AxStateOutput(AxReferenceKey.getNullKey(), eKey, nsKey)));
+ assertNotEquals(0, so.compareTo(new AxStateOutput(soKey, new AxArtifactKey(), nsKey)));
+ assertNotEquals(0, so.compareTo(new AxStateOutput(soKey, eKey, new AxReferenceKey())));
+ assertEquals(0, so.compareTo(new AxStateOutput(soKey, eKey, nsKey)));
+
+ assertNotNull(so.getKeys());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateTaskReferenceTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateTaskReferenceTest.java
new file mode 100644
index 000000000..568c47f61
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateTaskReferenceTest.java
@@ -0,0 +1,144 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Test state task references.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class StateTaskReferenceTest {
+
+ @Test
+ public void testStateTaskReference() {
+ assertNotNull(new AxStateTaskReference());
+ assertNotNull(new AxStateTaskReference(new AxReferenceKey()));
+ assertNotNull(new AxStateTaskReference(new AxReferenceKey(), AxStateTaskOutputType.UNDEFINED,
+ new AxReferenceKey()));
+ assertNotNull(new AxStateTaskReference(new AxReferenceKey(), new AxArtifactKey(),
+ AxStateTaskOutputType.UNDEFINED, new AxReferenceKey()));
+
+ AxStateTaskReference stRef = new AxStateTaskReference();
+
+ AxReferenceKey stRefKey = new AxReferenceKey("StateParent", "0.0.1", "SOState", "SOName");
+
+ assertThatThrownBy(() -> stRef.setKey(null))
+ .hasMessage("key may not be null");
+ stRef.setKey(stRefKey);
+ assertEquals("StateParent:0.0.1:SOState:SOName", stRef.getKey().getId());
+ assertEquals("StateParent:0.0.1:SOState:SOName", stRef.getKeys().get(0).getId());
+
+ assertThatThrownBy(() -> stRef.setStateTaskOutputType(null))
+ .hasMessage("outputType may not be null");
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
+ assertEquals(AxStateTaskOutputType.UNDEFINED, stRef.getStateTaskOutputType());
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.DIRECT);
+ assertEquals(AxStateTaskOutputType.DIRECT, stRef.getStateTaskOutputType());
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
+ assertEquals(AxStateTaskOutputType.LOGIC, stRef.getStateTaskOutputType());
+
+ assertThatThrownBy(() -> stRef.setOutput(null))
+ .hasMessage("output may not be null");
+ AxReferenceKey soKey = new AxReferenceKey("StateParent", "0.0.1", "SOState", "STRef0");
+ stRef.setOutput(soKey);
+ assertEquals(soKey, stRef.getOutput());
+
+ AxValidationResult result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ stRef.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ stRef.setKey(stRefKey);
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ stRef.setOutput(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ stRef.setOutput(soKey);
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ stRef.clean();
+
+ AxStateTaskReference clonedStRef = new AxStateTaskReference(stRef);
+ assertEquals("AxStateTaskReference:(stateKey=AxReferenceKey:(par", clonedStRef.toString().substring(0, 50));
+
+ assertNotEquals(0, stRef.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(stRef, stRef); // NOSONAR
+ assertEquals(stRef, clonedStRef);
+ assertNotNull(stRef);
+ assertNotEquals(stRef, (Object) "Hello");
+ assertNotEquals(stRef, new AxStateTaskReference(AxReferenceKey.getNullKey(), AxStateTaskOutputType.LOGIC,
+ soKey));
+ assertNotEquals(stRef, new AxStateTaskReference(stRefKey, AxStateTaskOutputType.DIRECT, soKey));
+ assertNotEquals(stRef, new AxStateTaskReference(stRefKey, AxStateTaskOutputType.LOGIC, new AxReferenceKey()));
+ assertEquals(stRef, new AxStateTaskReference(stRefKey, AxStateTaskOutputType.LOGIC, soKey));
+
+ assertNotNull(new AxStateTaskReference(new AxReferenceKey(), new AxArtifactKey(),
+ AxStateTaskOutputType.UNDEFINED, new AxReferenceKey()));
+
+ assertEquals(0, stRef.compareTo(stRef));
+ assertEquals(0, stRef.compareTo(clonedStRef));
+ assertNotEquals(0, stRef.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, stRef.compareTo(null));
+ assertNotEquals(0, stRef.compareTo(
+ new AxStateTaskReference(AxReferenceKey.getNullKey(), AxStateTaskOutputType.LOGIC, soKey)));
+ assertNotEquals(0, stRef.compareTo(new AxStateTaskReference(stRefKey, AxStateTaskOutputType.DIRECT, soKey)));
+ assertNotEquals(0, stRef.compareTo(
+ new AxStateTaskReference(stRefKey, AxStateTaskOutputType.LOGIC, new AxReferenceKey())));
+ assertEquals(0, stRef.compareTo(new AxStateTaskReference(stRefKey, AxStateTaskOutputType.LOGIC, soKey)));
+
+ assertNotNull(stRef.getKeys());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateTest.java
new file mode 100644
index 000000000..7fbe78078
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/StateTest.java
@@ -0,0 +1,461 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Test policy states.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class StateTest {
+
+ @Test
+ public void testState() {
+ final TreeMap<String, AxStateOutput> soEmptyMap = new TreeMap<>();
+ final TreeSet<AxArtifactKey> ctxtEmptySet = new TreeSet<>();
+ final TreeMap<String, AxStateFinalizerLogic> sflEmptyMap = new TreeMap<>();
+ final TreeMap<AxArtifactKey, AxStateTaskReference> trEmptyMap = new TreeMap<>();
+
+ final TreeMap<String, AxStateOutput> soMap = new TreeMap<>();
+ final TreeSet<AxArtifactKey> ctxtSet = new TreeSet<>();
+ final TreeMap<String, AxStateFinalizerLogic> sflMap = new TreeMap<>();
+ final TreeMap<AxArtifactKey, AxStateTaskReference> trMap = new TreeMap<>();
+
+ assertNotNull(new AxState());
+ assertNotNull(new AxState(new AxReferenceKey()));
+ assertNotNull(new AxState(new AxStateParamsBuilder().key(new AxReferenceKey()).trigger(new AxArtifactKey())
+ .stateOutputs(soEmptyMap).contextAlbumReferenceSet(ctxtEmptySet)
+ .taskSelectionLogic(new AxTaskSelectionLogic()).stateFinalizerLogicMap(sflEmptyMap)
+ .defaultTask(new AxArtifactKey()).taskReferenceMap(trEmptyMap)));
+
+ final AxState state = new AxState();
+
+ final AxReferenceKey stateKey = new AxReferenceKey("PolicyName", "0.0.1", "StateName");
+ final AxReferenceKey stateKeyNext = new AxReferenceKey("PolicyName", "0.0.1", "StateNameNext");
+ final AxReferenceKey stateKeyBad = new AxReferenceKey("PolicyName", "0.0.1", "BadStateName");
+ final AxArtifactKey triggerKey = new AxArtifactKey("TriggerName", "0.0.1");
+ final AxTaskSelectionLogic tsl = new AxTaskSelectionLogic(stateKey, "TSL", "LogicFlavour", "Some Logic");
+ final AxArtifactKey defTaskKey = new AxArtifactKey("TaskName", "0.0.1");
+ final AxArtifactKey taskKey1 = new AxArtifactKey("Task1", "0.0.1");
+ final AxArtifactKey taskKey2 = new AxArtifactKey("Task2", "0.0.1");
+ final AxArtifactKey taskKeyBad = new AxArtifactKey("TaskBad", "0.0.1");
+
+ assertThatThrownBy(() -> state.setKey(null))
+ .hasMessage("key may not be null");
+ state.setKey(stateKey);
+ assertEquals("PolicyName:0.0.1:NULL:StateName", state.getKey().getId());
+ assertEquals("PolicyName:0.0.1:NULL:StateName", state.getKeys().get(0).getId());
+
+ final AxStateOutput so0 = new AxStateOutput(new AxReferenceKey(stateKey, "SO0"), triggerKey,
+ new AxReferenceKey());
+ final AxStateOutput soU = new AxStateOutput(new AxReferenceKey(stateKey, "SOU"), triggerKey, stateKeyNext);
+ final AxStateOutput soSame = new AxStateOutput(new AxReferenceKey(stateKey, "SOU"), triggerKey, stateKey);
+ final AxArtifactKey cr0 = new AxArtifactKey("ContextReference", "0.0.1");
+ final AxStateFinalizerLogic sfl = new AxStateFinalizerLogic(stateKey, "SFLogicName", "LogicFlavour", "Logic");
+ final AxStateFinalizerLogic sflU = new AxStateFinalizerLogic(stateKey, "UnusedSFLogicName", "LogicFlavour",
+ "Logic");
+ final AxStateTaskReference str0 = new AxStateTaskReference(new AxReferenceKey(stateKey, "STR0"),
+ AxStateTaskOutputType.DIRECT, so0.getKey());
+ final AxStateTaskReference str1 = new AxStateTaskReference(new AxReferenceKey(stateKey, "STR1"),
+ AxStateTaskOutputType.DIRECT, so0.getKey());
+ final AxStateTaskReference str2 = new AxStateTaskReference(new AxReferenceKey(stateKey, "STR2"),
+ AxStateTaskOutputType.LOGIC, sfl.getKey());
+
+ final AxStateTaskReference strBadState = new AxStateTaskReference(new AxReferenceKey(stateKeyBad, "STR2"),
+ AxStateTaskOutputType.LOGIC, sfl.getKey());
+ final AxStateTaskReference strBadStateOutput = new AxStateTaskReference(new AxReferenceKey(stateKey, "STR2"),
+ AxStateTaskOutputType.UNDEFINED, sfl.getKey());
+ final AxStateTaskReference strBadStateFinalizerLogic = new AxStateTaskReference(
+ new AxReferenceKey(stateKeyBad, "STR2"), AxStateTaskOutputType.LOGIC,
+ new AxReferenceKey(stateKey, "SomeSFL"));
+
+ soMap.put(so0.getKey().getLocalName(), so0);
+ ctxtSet.add(cr0);
+ sflMap.put(sfl.getKey().getLocalName(), sfl);
+ trMap.put(defTaskKey.getKey(), str0);
+ trMap.put(taskKey1.getKey(), str1);
+ trMap.put(taskKey2.getKey(), str2);
+
+ assertThatThrownBy(() -> state.setTrigger(null))
+ .hasMessage("trigger may not be null");
+ state.setTrigger(triggerKey);
+ assertEquals(triggerKey, state.getTrigger());
+
+ assertThatThrownBy(() -> state.setStateOutputs(null))
+ .hasMessage("stateOutputs may not be null");
+ state.setStateOutputs(soMap);
+ assertEquals(soMap, state.getStateOutputs());
+
+ assertThatThrownBy(() -> state.setContextAlbumReferences(null))
+ .hasMessage("contextAlbumReferenceSet may not be null");
+ state.setContextAlbumReferences(ctxtSet);
+ assertEquals(ctxtSet, state.getContextAlbumReferences());
+
+ assertThatThrownBy(() -> state.setTaskSelectionLogic(null))
+ .hasMessage("taskSelectionLogic may not be null");
+ assertEquals(false, state.checkSetTaskSelectionLogic());
+ state.setTaskSelectionLogic(tsl);
+ assertEquals(tsl, state.getTaskSelectionLogic());
+ assertEquals(true, state.checkSetTaskSelectionLogic());
+
+ assertThatThrownBy(() -> state.setStateFinalizerLogicMap(null))
+ .hasMessage("stateFinalizerLogic may not be null");
+ state.setStateFinalizerLogicMap(sflMap);
+ assertEquals(sflMap, state.getStateFinalizerLogicMap());
+
+ assertThatThrownBy(() -> state.setDefaultTask(null))
+ .hasMessage("defaultTask may not be null");
+ state.setDefaultTask(defTaskKey);
+ assertEquals(defTaskKey, state.getDefaultTask());
+
+ assertThatThrownBy(() -> state.setTaskReferences(null))
+ .hasMessage("taskReferenceMap may not be null");
+ state.setTaskReferences(trMap);
+ assertEquals(trMap, state.getTaskReferences());
+
+ state.buildReferences();
+ assertEquals(state.getKey(), state.getKeys().get(0));
+ state.getTaskSelectionLogic().getKey().setLocalName(AxKey.NULL_KEY_NAME);
+ state.buildReferences();
+ assertEquals(state.getKey(), state.getKeys().get(0));
+
+ final Set<String> stateSet = state.getNextStateSet();
+ assertEquals(1, stateSet.size());
+
+ AxValidationResult result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setKey(stateKey);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setTrigger(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setTrigger(triggerKey);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setStateOutputs(soEmptyMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ so0.getKey().setParentLocalName("Zooby");
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ so0.getKey().setParentLocalName("StateName");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ soMap.put("NullOutput", null);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ soMap.remove("NullOutput");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ soMap.put("DupOutput", so0);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ soMap.remove("DupOutput");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ soMap.put("UnusedOutput", soU);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ soMap.remove("UnusedOutput");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ soMap.put("OutputToSameState", soSame);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ soMap.remove("OutputToSameState");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Empty context reference set is OK
+ state.setContextAlbumReferences(ctxtEmptySet);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setContextAlbumReferences(ctxtSet);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ ctxtSet.add(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ ctxtSet.remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Null TSL is OK
+ state.getTaskSelectionLogic().setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.getTaskSelectionLogic().setKey(new AxReferenceKey(stateKey, "TSL"));
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setDefaultTask(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setDefaultTask(defTaskKey);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setTaskReferences(trEmptyMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setTaskReferences(trMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(AxArtifactKey.getNullKey(), str0);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(taskKeyBad, strBadStateOutput);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(taskKeyBad);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(taskKeyBad, strBadState);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(taskKeyBad);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(taskKeyBad, strBadStateFinalizerLogic);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(taskKeyBad);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setDefaultTask(new AxArtifactKey("NonExistantTask", "0.0.1"));
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setDefaultTask(defTaskKey);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ sflMap.put("NullSFL", null);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ sflMap.remove("NullSFL");
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ sflMap.put(sflU.getKey().getLocalName(), sflU);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ sflMap.remove(sflU.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.clean();
+
+ final AxState clonedState = new AxState(state);
+ assertEquals("AxState:(stateKey=AxReferenceKey:(parent", clonedState.toString().substring(0, 40));
+
+ assertNotEquals(0, state.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(state, state); // NOSONAR
+ assertEquals(state, clonedState);
+ assertNotNull(state);
+
+ Object helloObj = "Hello";
+ assertNotEquals(state, helloObj);
+ assertNotEquals(state, new AxState(new AxStateParamsBuilder().key(new AxReferenceKey()).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trMap)));
+ assertNotEquals(state, new AxState(new AxStateParamsBuilder().key(stateKey).trigger(new AxArtifactKey())
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trMap)));
+ assertNotEquals(state, new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soEmptyMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trMap)));
+ assertNotEquals(state, new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtEmptySet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trMap)));
+ assertNotEquals(state, new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet)
+ .taskSelectionLogic(new AxTaskSelectionLogic()).stateFinalizerLogicMap(sflMap)
+ .defaultTask(defTaskKey).taskReferenceMap(trMap)));
+ assertNotEquals(state, new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflEmptyMap).defaultTask(defTaskKey).taskReferenceMap(trMap)));
+ assertNotEquals(state, new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(new AxArtifactKey()).taskReferenceMap(trMap)));
+ assertNotEquals(state, new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trEmptyMap)));
+ assertEquals(state, new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trMap)));
+
+ assertEquals(0, state.compareTo(state));
+ assertEquals(0, state.compareTo(clonedState));
+ assertNotEquals(0, state.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, state.compareTo(null));
+ assertNotEquals(0,
+ state.compareTo(new AxState(new AxStateParamsBuilder().key(new AxReferenceKey())
+ .trigger(triggerKey).stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet)
+ .taskSelectionLogic(tsl).stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey)
+ .taskReferenceMap(trMap))));
+ assertNotEquals(0, state.compareTo(new AxState(new AxStateParamsBuilder().key(stateKey)
+ .trigger(new AxArtifactKey()).stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet)
+ .taskSelectionLogic(tsl).stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey)
+ .taskReferenceMap(trMap))));
+ assertNotEquals(0, state.compareTo(new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soEmptyMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trMap))));
+ assertNotEquals(0, state.compareTo(new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtEmptySet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trMap))));
+ assertNotEquals(0,
+ state.compareTo(new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet)
+ .taskSelectionLogic(new AxTaskSelectionLogic()).stateFinalizerLogicMap(sflMap)
+ .defaultTask(defTaskKey).taskReferenceMap(trMap))));
+ assertNotEquals(0, state.compareTo(new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflEmptyMap).defaultTask(defTaskKey).taskReferenceMap(trMap))));
+ assertNotEquals(0, state.compareTo(new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(new AxArtifactKey()).taskReferenceMap(trMap))));
+ assertNotEquals(0, state.compareTo(new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trEmptyMap))));
+ assertEquals(0, state.compareTo(new AxState(new AxStateParamsBuilder().key(stateKey).trigger(triggerKey)
+ .stateOutputs(soMap).contextAlbumReferenceSet(ctxtSet).taskSelectionLogic(tsl)
+ .stateFinalizerLogicMap(sflMap).defaultTask(defTaskKey).taskReferenceMap(trMap))));
+
+ assertNotNull(state.getKeys());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TaskParameterTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TaskParameterTest.java
new file mode 100644
index 000000000..4255b495d
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TaskParameterTest.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+
+/**
+ * Test task parameters.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TaskParameterTest {
+
+ @Test
+ public void testTaskParameter() {
+ assertNotNull(new AxTaskParameter());
+ assertNotNull(new AxTaskParameter(new AxReferenceKey()));
+ assertNotNull(new AxTaskParameter(new AxReferenceKey(), "DefaultValue"));
+
+ final AxTaskParameter par = new AxTaskParameter();
+
+ final AxReferenceKey parKey = new AxReferenceKey("ParParentName", "0.0.1", "PLN", "LN");
+ par.setKey(parKey);
+ assertEquals("ParParentName:0.0.1:PLN:LN", par.getKey().getId());
+ assertEquals("ParParentName:0.0.1:PLN:LN", par.getKeys().get(0).getId());
+
+ par.setDefaultValue("DefaultValue");
+ assertEquals("DefaultValue", par.getTaskParameterValue());
+
+ AxValidationResult result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ par.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ par.setKey(parKey);
+ result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ assertThatThrownBy(() -> par.setDefaultValue(null))
+ .hasMessage("defaultValue may not be null");
+ par.setDefaultValue("");
+ result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(ValidationResult.WARNING, result.getValidationResult());
+
+ par.setDefaultValue("DefaultValue");
+ result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ par.clean();
+
+ final AxTaskParameter clonedPar = new AxTaskParameter(par);
+ assertEquals("AxTaskParameter:(key=AxReferenceKey:(parentKeyName=ParParentName,parentKeyVersion=0.0.1,"
+ + "parentLocalName=PLN,localName=LN),defaultValue=DefaultValue)", clonedPar.toString());
+
+ assertNotEquals(0, par.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(par, par); // NOSONAR
+ assertEquals(par, clonedPar);
+ assertNotNull(par);
+ assertNotEquals(par, (Object) "Hello");
+ assertNotEquals(par, new AxTaskParameter(AxReferenceKey.getNullKey(), "DefaultValue"));
+ assertNotEquals(par, new AxTaskParameter(parKey, "OtherDefaultValue"));
+ assertEquals(par, new AxTaskParameter(parKey, "DefaultValue"));
+
+ assertEquals(0, par.compareTo(par));
+ assertEquals(0, par.compareTo(clonedPar));
+ assertNotEquals(0, par.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, par.compareTo(null));
+ assertNotEquals(0, par.compareTo(new AxTaskParameter(AxReferenceKey.getNullKey(), "DefaultValue")));
+ assertNotEquals(0, par.compareTo(new AxTaskParameter(parKey, "OtherDefaultValue")));
+ assertEquals(0, par.compareTo(new AxTaskParameter(parKey, "DefaultValue")));
+
+ assertNotNull(par.getKeys());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TasksTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TasksTest.java
new file mode 100644
index 000000000..9c7866c85
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TasksTest.java
@@ -0,0 +1,259 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+
+/**
+ * Test policy tasks.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TasksTest {
+
+ @Test
+ public void testTasks() {
+ final TreeMap<String, AxTaskParameter> tpEmptyMap = new TreeMap<>();
+ final TreeSet<AxArtifactKey> ctxtEmptySet = new TreeSet<>();
+
+ final TreeMap<String, AxTaskParameter> tpMap = new TreeMap<>();
+ final TreeSet<AxArtifactKey> ctxtSet = new TreeSet<>();
+
+ assertNotNull(new AxTask());
+ assertNotNull(new AxTask(new AxArtifactKey()));
+ assertNotNull(new AxTask(new AxArtifactKey(), tpMap, ctxtSet, new AxTaskLogic()));
+
+ final AxTask task = new AxTask();
+
+ final AxArtifactKey taskKey = new AxArtifactKey("TaskName", "0.0.1");
+ task.setKey(taskKey);
+ assertEquals("TaskName:0.0.1", task.getKey().getId());
+ assertEquals("TaskName:0.0.1", task.getKeys().get(0).getId());
+
+ final AxTaskParameter tp0 = new AxTaskParameter(new AxReferenceKey(taskKey, "TP0"), "DefaultValue");
+ final AxArtifactKey cr0 = new AxArtifactKey("ContextReference", "0.0.1");
+ final AxTaskLogic tl = new AxTaskLogic(taskKey, "LogicName", "LogicFlavour", "Logic");
+
+ tpMap.put(tp0.getKey().getLocalName(), tp0);
+ ctxtSet.add(cr0);
+
+ task.setInputEvent(new AxEvent());
+ task.setOutputEvents(Map.of("Event", new AxEvent()));
+
+ task.setTaskParameters(tpMap);
+ assertEquals(tpMap, task.getTaskParameters());
+
+ task.setContextAlbumReferences(ctxtSet);
+ assertEquals(ctxtSet, task.getContextAlbumReferences());
+
+ task.setTaskLogic(tl);
+ assertEquals(tl, task.getTaskLogic());
+
+ task.setKey(taskKey);
+ assertEquals("TaskName:0.0.1", task.getKey().getId());
+ assertEquals("TaskName:0.0.1", task.getKeys().get(0).getId());
+
+ task.buildReferences();
+ assertEquals(1, task.getTaskParameters().size());
+
+ AxValidationResult result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ task.setKey(taskKey);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Empty task parameter map is OK
+ task.setTaskParameters(tpEmptyMap);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.setTaskParameters(tpMap);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tpMap.put("NullField", null);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tpMap.remove("NullField");
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Empty context reference set is OK
+ task.setContextAlbumReferences(ctxtEmptySet);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.setContextAlbumReferences(ctxtSet);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ ctxtSet.add(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ ctxtSet.remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.clean();
+
+ final AxTask clonedTask = new AxTask(task);
+ assertEquals("AxTask:(key=AxArtifactKey:(name=TaskName", clonedTask.toString().substring(0, 40));
+
+ assertNotEquals(0, task.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(task, task); // NOSONAR
+ assertEquals(task, clonedTask);
+ assertNotNull(task);
+
+ Object helloObj = "Hello";
+ assertNotEquals(task, helloObj);
+ assertNotEquals(task, new AxTask(new AxArtifactKey(), tpMap, ctxtSet, tl));
+ assertEquals(task, new AxTask(taskKey, tpMap, ctxtSet, tl));
+ assertNotEquals(task, new AxTask(taskKey, tpEmptyMap, ctxtSet, tl));
+ assertNotEquals(task, new AxTask(taskKey, tpMap, ctxtEmptySet, tl));
+ assertNotEquals(task, new AxTask(taskKey, tpMap, ctxtSet, new AxTaskLogic()));
+ assertEquals(task, new AxTask(taskKey, tpMap, ctxtSet, tl));
+
+ assertEquals(0, task.compareTo(task));
+ assertEquals(0, task.compareTo(clonedTask));
+ assertNotEquals(0, task.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, task.compareTo(null));
+ assertNotEquals(0, task.compareTo(new AxTask(new AxArtifactKey(), tpMap, ctxtSet, tl)));
+ assertEquals(0, task.compareTo(new AxTask(taskKey, tpMap, ctxtSet, tl)));
+ assertNotEquals(0, task.compareTo(new AxTask(taskKey, tpEmptyMap, ctxtSet, tl)));
+ assertNotEquals(0, task.compareTo(new AxTask(taskKey, tpMap, ctxtEmptySet, tl)));
+ assertNotEquals(0, task.compareTo(new AxTask(taskKey, tpMap, ctxtSet, new AxTaskLogic())));
+ assertEquals(0, task.compareTo(new AxTask(taskKey, tpMap, ctxtSet, tl)));
+
+ assertNotNull(task.getKeys());
+
+ final AxTasks tasks = new AxTasks();
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ // Invalid, no tasks in task map
+ tasks.setKey(new AxArtifactKey("TasksKey", "0.0.1"));
+ assertEquals("TasksKey:0.0.1", tasks.getKey().getId());
+
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tasks.getTaskMap().put(taskKey, task);
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tasks.getTaskMap().put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tasks.getTaskMap().remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tasks.getTaskMap().put(new AxArtifactKey("NullValueKey", "0.0.1"), null);
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tasks.getTaskMap().remove(new AxArtifactKey("NullValueKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tasks.getTaskMap().put(new AxArtifactKey("BadTaskKey", "0.0.1"), task);
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tasks.getTaskMap().remove(new AxArtifactKey("BadTaskKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tasks.clean();
+
+ final AxTasks clonedTasks = new AxTasks(tasks);
+ assertEquals("AxTasks:(key=AxArtifactKey:(name=TasksKey,version=0.0.1),tas",
+ clonedTasks.toString().substring(0, 60));
+
+ assertNotEquals(0, tasks.hashCode());
+
+ // disabling sonar because this code tests the equals() method
+ assertEquals(tasks, tasks); // NOSONAR
+ assertEquals(tasks, clonedTasks);
+ assertNotNull(tasks);
+ assertNotEquals(tasks, helloObj);
+ assertNotEquals(tasks, new AxTasks(new AxArtifactKey()));
+
+ assertEquals(0, tasks.compareTo(tasks));
+ assertEquals(0, tasks.compareTo(clonedTasks));
+ assertNotEquals(0, tasks.compareTo(null));
+ assertNotEquals(0, tasks.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, tasks.compareTo(new AxTasks(new AxArtifactKey())));
+
+ clonedTasks.get(taskKey).getTaskLogic().setLogic("SomeChangedLogic");
+ assertNotEquals(0, tasks.compareTo(clonedTasks));
+
+ assertEquals(tasks.getKey(), tasks.getKeys().get(0));
+
+ assertEquals("TaskName", tasks.get("TaskName").getKey().getName());
+ assertEquals("TaskName", tasks.get("TaskName", "0.0.1").getKey().getName());
+ assertEquals(1, tasks.getAll("TaskName", "0.0.1").size());
+ assertEquals(0, tasks.getAll("NonExistantTaskName").size());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/ApexPolicyModelTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/ApexPolicyModelTest.java
new file mode 100644
index 000000000..48e4f87f9
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/ApexPolicyModelTest.java
@@ -0,0 +1,138 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+public class ApexPolicyModelTest {
+ private static final String VALID_MODEL_STRING = "***validation of model successful***";
+
+ private static final String OBSERVATION_MODEL_STRING = "\n"
+ + "***observations noted during validation of model***\n"
+ + "AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,"
+ + "localName=state):org.onap.policy.apex.model.policymodel.concepts.AxState:OBSERVATION:"
+ + "state output stateOutput0 is not used directly by any task\n"
+ + "********************************";
+
+ private static final String WARNING_MODEL_STRING = "\n" + "***warnings issued during validation of model***\n"
+ + "AxArtifactKey:(name=policy,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicy:WARNING:state AxReferenceKey:"
+ + "(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=anotherState) "
+ + "is not referenced in the policy execution tree\n" + "********************************";
+
+ private static final String INVALID_MODEL_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=contextAlbum0,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum:INVALID:scope is not defined\n"
+ + "AxArtifactKey:(name=contextAlbum1,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum:INVALID:scope is not defined\n"
+ + "********************************";
+
+ private static final String INVALID_MODEL_MALSTRUCTURED_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=policyModel_KeyInfo,version=0.0.1):"
+ + "org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation:INVALID:"
+ + "keyInfoMap may not be empty\n" + "AxArtifactKey:(name=policyModel,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=policyModel,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=policyModel_KeyInfo,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=policyModel_Schemas,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=policyModel_Events,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=policyModel_Albums,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=policyModel_Tasks,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:"
+ + "key information not found for key AxArtifactKey:(name=policyModel_Policies,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel_Schemas,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas:INVALID:"
+ + "contextSchemas may not be empty\n" + "AxArtifactKey:(name=policyModel_Events,version=0.0.1):"
+ + "org.onap.policy.apex.model.eventmodel.concepts.AxEvents:INVALID:eventMap may not be empty\n"
+ + "AxArtifactKey:(name=policyModel_Albums,version=0.0.1):"
+ + "org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums:OBSERVATION:albums are empty\n"
+ + "AxArtifactKey:(name=policyModel_Tasks,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxTasks:INVALID:taskMap may not be empty\n"
+ + "AxArtifactKey:(name=policyModel_Policies,version=0.0.1)"
+ + ":org.onap.policy.apex.model.policymodel.concepts.AxPolicies:INVALID:policyMap may not be empty\n"
+ + "********************************";
+
+ TestApexModel<AxPolicyModel> testApexModel;
+
+ /**
+ * Set up the policy model tests.
+ *
+ * @throws Exception on setup errors
+ */
+ @Before
+ public void setup() throws Exception {
+ testApexModel = new TestApexModel<AxPolicyModel>(AxPolicyModel.class, new SupportApexPolicyModelCreator());
+ }
+
+ @Test
+ public void testModelValid() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelValid();
+ assertEquals(VALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testApexModelVaidateObservation() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateObservation();
+ assertEquals(OBSERVATION_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testApexModelVaidateWarning() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateWarning();
+ assertEquals(WARNING_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateInvalidModel() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateInvalidModel();
+ assertEquals(INVALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateMalstructured() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateMalstructured();
+ assertEquals(INVALID_MODEL_MALSTRUCTURED_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelWriteReadJson() throws Exception {
+ testApexModel.testApexModelWriteReadJson();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyserTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyserTest.java
new file mode 100644
index 000000000..b1e2d5cbd
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyserTest.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+public class PolicyAnalyserTest {
+ @Test
+ public void test() {
+ final AxPolicyModel apexModel = new SupportApexPolicyModelCreator().getModel();
+
+ final PolicyAnalyser policyAnalyser = new PolicyAnalyser();
+ final PolicyAnalysisResult analysisResult = policyAnalyser.analyse(apexModel);
+
+ assertEquals(EXPECTED_ANALYSIS_RESULT, analysisResult.toString());
+
+ assertNotNull(analysisResult.getUsedContextAlbums());
+ assertNotNull(analysisResult.getUsedContextSchemas());
+ assertNotNull(analysisResult.getUsedEvents());
+ assertNotNull(analysisResult.getUsedTasks());
+ assertNotNull(analysisResult.getUnusedContextAlbums());
+ assertNotNull(analysisResult.getUnusedContextSchemas());
+ assertNotNull(analysisResult.getUnusedEvents());
+ assertNotNull(analysisResult.getUnusedTasks());
+ }
+
+ private static final String EXPECTED_ANALYSIS_RESULT = "" + "Context Schema usage\n" + " MapType:0.0.1\n"
+ + " contextAlbum0:0.0.1\n" + " StringType:0.0.1\n" + " contextAlbum1:0.0.1\n"
+ + " eventContextItem0:0.0.1\n" + " inEvent:0.0.1\n" + " outEvent0:0.0.1\n" + " outEvent1:0.0.1\n"
+ + " eventContextItem1:0.0.1\n" + " inEvent:0.0.1\n" + " outEvent0:0.0.1\n"
+ + " outEvent1:0.0.1\n" + "Context Album usage\n" + " contextAlbum0:0.0.1\n"
+ + " task:0.0.1\n" + " policy:0.0.1:NULL:state\n" + " contextAlbum1:0.0.1\n" + " task:0.0.1\n"
+ + " policy:0.0.1:NULL:state\n" + "Event usage\n" + " inEvent:0.0.1\n" + " policy:0.0.1:NULL:state\n"
+ + " outEvent0:0.0.1\n" + " policy:0.0.1:NULL:state\n" + " outEvent1:0.0.1 (unused)\n" + "Task usage\n"
+ + " task:0.0.1\n" + " policy:0.0.1:NULL:state\n";
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReaderTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReaderTest.java
new file mode 100644
index 000000000..a2cbe7415
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReaderTest.java
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.policymodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.policymodel.concepts.AxLogic;
+
+/**
+ * Logic reader for policy tests.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyLogicReaderTest {
+
+ @Test
+ public void test() {
+ final AxReferenceKey logicKey = new AxReferenceKey("LogicParent", "0.0.1", "LogicInstanceName");
+
+ final PolicyLogicReader plReader = new PolicyLogicReader();
+
+ plReader.setLogicPackage("somewhere.over.the.rainbow");
+ assertEquals("somewhere.over.the.rainbow", plReader.getLogicPackage());
+
+ plReader.setDefaultLogic("FunkyDefaultLogic");
+ assertEquals("FunkyDefaultLogic", plReader.getDefaultLogic());
+
+ assertThatThrownBy(() -> new AxLogic(logicKey, "FunkyLogic", plReader))
+ .hasMessage("logic not found for logic "
+ + "\"somewhere/over/the/rainbow/funkylogic/FunkyDefaultLogic.funkylogic\"");
+ plReader.setDefaultLogic(null);
+ assertThatThrownBy(() -> new AxLogic(logicKey, "FunkyLogic", plReader))
+ .hasMessage("logic not found for logic "
+ + "\"somewhere/over/the/rainbow/funkylogic/LogicParentLogicInstanceName.funkylogic\"");
+ logicKey.setParentLocalName("LogicParentLocalName");
+ assertThatThrownBy(() -> new AxLogic(logicKey, "FunkyLogic", plReader))
+ .hasMessage("logic not found for logic " + "\"somewhere/over/the/rainbow/funkylogic/"
+ + "LogicParentLogicParentLocalNameLogicInstanceName.funkylogic\"");
+ plReader.setLogicPackage("path.to.apex.logic");
+
+ AxLogic logic = new AxLogic(logicKey, "FunkyLogic", plReader);
+ assertThat(logic.getLogic()).endsWith("Way out man, this is funky logic!");
+
+ plReader.setLogicPackage("somewhere.over.the.rainbow");
+ plReader.setDefaultLogic("JavaLogic");
+
+ logic = new AxLogic(logicKey, "JAVA", plReader);
+ assertEquals("somewhere.over.the.rainbow.java.JavaLogic", logic.getLogic());
+
+ plReader.setDefaultLogic(null);
+
+ logic = new AxLogic(logicKey, "JAVA", plReader);
+ assertEquals("somewhere.over.the.rainbow.java.LogicParentLogicParentLocalNameLogicInstanceName",
+ logic.getLogic());
+
+ logicKey.setParentLocalName(AxKey.NULL_KEY_NAME);
+ logic = new AxLogic(logicKey, "JAVA", plReader);
+ assertEquals("somewhere.over.the.rainbow.java.LogicParentLogicInstanceName", logic.getLogic());
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparerTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparerTest.java
new file mode 100644
index 000000000..691880d6b
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparerTest.java
@@ -0,0 +1,118 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020,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.onap.policy.apex.model.policymodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.UUID;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+
+public class PolicyModelComparerTest {
+
+ @Test
+ public void testPolicyComparer() throws IOException {
+ final AxPolicyModel leftApexModel = new SupportApexPolicyModelCreator().getModel();
+ final AxPolicyModel rightApexModel = new AxPolicyModel(leftApexModel);
+
+ PolicyModelComparer policyModelComparer = new PolicyModelComparer(leftApexModel, rightApexModel);
+
+ String resultString = policyModelComparer.asString(false, false);
+ String checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt");
+ assertEquals(resultString.trim().replaceAll("\\s+", ""), checkString.trim().replaceAll("\\s+", ""));
+
+ resultString = policyModelComparer.asString(false, true);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt");
+ assertEquals(checkString.trim().replaceAll("\\s+", ""), resultString.trim().replaceAll("\\s+", ""));
+
+ resultString = policyModelComparer.asString(true, false);
+ checkString =
+ TextFileUtils.getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt");
+ assertEquals(checkString.trim().replaceAll("\\s+", ""), resultString.trim().replaceAll("\\s+", ""));
+
+ resultString = policyModelComparer.asString(true, true);
+ checkString =
+ TextFileUtils.getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt");
+ assertEquals(checkString.trim().replaceAll("\\s+", ""), resultString.trim().replaceAll("\\s+", ""));
+
+ final AxKeyInfo leftOnlyKeyInfo = new AxKeyInfo(new AxArtifactKey("LeftOnlyKeyInfo", "0.0.1"),
+ UUID.fromString("ce9168c-e6df-414f-9646-6da464b6f000"), "Left only key info");
+ final AxKeyInfo rightOnlyKeyInfo = new AxKeyInfo(new AxArtifactKey("RightOnlyKeyInfo", "0.0.1"),
+ UUID.fromString("ce9168c-e6df-414f-9646-6da464b6f001"), "Right only key info");
+
+ leftApexModel.getKeyInformation().getKeyInfoMap().put(leftOnlyKeyInfo.getKey(), leftOnlyKeyInfo);
+ rightApexModel.getKeyInformation().getKeyInfoMap().put(rightOnlyKeyInfo.getKey(), rightOnlyKeyInfo);
+
+ leftApexModel.getKeyInformation().getKeyInfoMap().get(new AxArtifactKey("inEvent", "0.0.1"))
+ .setDescription("Left InEvent Description");
+ rightApexModel.getKeyInformation().getKeyInfoMap().get(new AxArtifactKey("inEvent", "0.0.1"))
+ .setDescription("Right InEvent Description");
+
+ policyModelComparer = new PolicyModelComparer(leftApexModel, rightApexModel);
+
+ resultString = policyModelComparer.asString(false, false);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt");
+ assertEquals(resultString.trim().replaceAll("\\s+", ""), checkString.trim().replaceAll("\\s+", ""));
+
+ resultString = policyModelComparer.asString(false, true);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt");
+ assertEquals(checkString.trim().replaceAll("\\s+", ""), resultString.trim().replaceAll("\\s+", ""));
+
+ resultString = policyModelComparer.asString(true, false);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt");
+ assertEquals(checkString.trim().replaceAll("\\s+", ""), resultString.trim().replaceAll("\\s+", ""));
+
+ resultString = policyModelComparer.asString(true, true);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt");
+ assertEquals(checkString.trim().replaceAll("\\s+", ""), resultString.trim().replaceAll("\\s+", ""));
+
+ assertNotNull(policyModelComparer.getContextAlbumComparisonResult());
+ assertNotNull(policyModelComparer.getContextAlbumKeyDifference());
+ assertNotNull(policyModelComparer.getContextSchemaComparisonResult());
+ assertNotNull(policyModelComparer.getContextSchemaKeyDifference());
+ assertNotNull(policyModelComparer.getEventComparisonResult());
+ assertNotNull(policyModelComparer.getEventKeyDifference());
+ assertNotNull(policyModelComparer.getKeyInfoComparisonResult());
+ assertNotNull(policyModelComparer.getKeyInformationKeyDifference());
+ assertNotNull(policyModelComparer.getPolicyComparisonResult());
+ assertNotNull(policyModelComparer.getPolicykeyDifference());
+ assertNotNull(policyModelComparer.getPolicyModelsKeyDifference());
+ assertNotNull(policyModelComparer.getTaskComparisonResult());
+ assertNotNull(policyModelComparer.getTaskKeyDifference());
+
+ assertNotNull(new PolicyComparer().compare(leftApexModel.getPolicies(), rightApexModel.getPolicies()));
+
+ assertEquals("****** policy map differences ******\n*** context s",
+ policyModelComparer.toString().substring(0, 50));
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMergerTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMergerTest.java
new file mode 100644
index 000000000..2bdf7499f
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMergerTest.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2020 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic;
+
+/**
+ * Test model merging.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyModelMergerTest {
+
+ @Test
+ public void testPolicyModelMerger() throws ApexModelException {
+ final AxPolicyModel leftPolicyModel = new SupportApexPolicyModelCreator().getModel();
+ final AxPolicyModel rightPolicyModel = new SupportApexPolicyModelCreator().getModel();
+
+ AxPolicyModel mergedPolicyModel =
+ PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, false);
+ assertEquals(leftPolicyModel, mergedPolicyModel);
+ assertEquals(rightPolicyModel, mergedPolicyModel);
+
+ leftPolicyModel.setKey(new AxArtifactKey("LeftPolicyModel", "0.0.1"));
+ assertThatThrownBy(
+ () -> PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, false))
+ .hasMessageContaining("left model is invalid: \n***validation of model failed");
+
+ leftPolicyModel.setKey(new AxArtifactKey("LeftPolicyModel", "0.0.1"));
+ assertNotNull(PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, true, false));
+
+ leftPolicyModel.getKeyInformation().generateKeyInfo(leftPolicyModel);
+ mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, true, false);
+ assertNotNull(mergedPolicyModel);
+
+ rightPolicyModel.setKey(new AxArtifactKey("RightPolicyModel", "0.0.1"));
+ assertThatThrownBy(
+ () -> PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, false))
+ .hasMessageContaining("right model is invalid: \n***validation of model failed");
+
+ rightPolicyModel.setKey(new AxArtifactKey("RightPolicyModel", "0.0.1"));
+ assertNotNull(PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, true, false));
+
+ rightPolicyModel.getKeyInformation().generateKeyInfo(rightPolicyModel);
+ mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, false);
+ assertNotNull(mergedPolicyModel);
+
+ final AxPolicyModel rightPolicyModel2 = new SupportApexPolicyModelCreator().getAnotherModel();
+ mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel2, true, false);
+ assertNotNull(mergedPolicyModel);
+
+ mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel2, true, true);
+ assertNotNull(mergedPolicyModel);
+
+ final AxPolicyModel rightPolicyModel3 = new SupportApexPolicyModelCreator().getModel();
+ AxArtifactKey taskArtifactKey = new AxArtifactKey("task", "0.0.1");
+ // fail when concepts in two policies have same name but different definition
+ // here make up some change so as to update the definition of the task in second policy
+ rightPolicyModel3.getTasks().getTaskMap().get(taskArtifactKey)
+ .setTaskLogic(new AxTaskLogic(taskArtifactKey, "logicName", "logicFlavour", "logicImpl"));
+ assertThatThrownBy(() -> PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel3, true, true))
+ .hasMessage("\n Same task - task:0.0.1 with different definitions used in different policies");
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitterTest.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitterTest.java
new file mode 100644
index 000000000..902206d51
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitterTest.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.policymodel.handling;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Set;
+import java.util.TreeSet;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+public class PolicyModelSplitterTest {
+ @Test
+ public void test() throws ApexModelException {
+ final AxPolicyModel apexModel = new SupportApexPolicyModelCreator().getModel();
+
+ final Set<AxArtifactKey> requiredPolicySet = new TreeSet<AxArtifactKey>();
+ requiredPolicySet.add(new AxArtifactKey("policy", "0.0.1"));
+
+ // There's only one policy so a split of this model on that policy should return the same
+ // model
+ AxPolicyModel splitApexModel = null;
+ splitApexModel = PolicyModelSplitter.getSubPolicyModel(apexModel, requiredPolicySet);
+
+ // The only difference between the models should be that the unused event outEvent1 should
+ // not be in the split model
+ apexModel.getEvents().getEventMap().remove(new AxArtifactKey("outEvent1", "0.0.1"));
+ apexModel.getKeyInformation().getKeyInfoMap().remove(new AxArtifactKey("outEvent1", "0.0.1"));
+ assertEquals(apexModel, splitApexModel);
+
+ final Set<AxArtifactKey> requiredMissingPolicySet = new TreeSet<AxArtifactKey>();
+ requiredPolicySet.add(new AxArtifactKey("MissingPolicy", "0.0.1"));
+
+ AxPolicyModel missingSplitApexModel = null;
+ missingSplitApexModel = PolicyModelSplitter.getSubPolicyModel(apexModel, requiredMissingPolicySet);
+ assertNotNull(missingSplitApexModel);
+
+ splitApexModel = null;
+ splitApexModel = PolicyModelSplitter.getSubPolicyModel(apexModel, requiredPolicySet, true);
+
+ // The only difference between the models should be that the unused event outEvent1 should
+ // not be in the split model
+ apexModel.getEvents().getEventMap().remove(new AxArtifactKey("outEvent1", "0.0.1"));
+ apexModel.getKeyInformation().getKeyInfoMap().remove(new AxArtifactKey("outEvent1", "0.0.1"));
+ assertEquals(apexModel, splitApexModel);
+
+ // There's only one policy so a split of this model on that policy should return the same
+ // model
+ apexModel.getKey().setName("InvalidPolicyModelName");
+ assertThatThrownBy(() -> PolicyModelSplitter.getSubPolicyModel(apexModel, requiredPolicySet))
+ .hasMessageContaining("source model is invalid: \n***validation of model f");
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/SupportApexPolicyModelCreator.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/SupportApexPolicyModelCreator.java
new file mode 100644
index 000000000..85040221a
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/handling/SupportApexPolicyModelCreator.java
@@ -0,0 +1,406 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.handling;
+
+import java.util.Map;
+import java.util.UUID;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicies;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxState;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTasks;
+
+/**
+ * Model creator for model tests.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class SupportApexPolicyModelCreator implements TestApexModelCreator<AxPolicyModel> {
+
+ @Override
+ public AxPolicyModel getModel() {
+ final AxContextSchema schema0 = new AxContextSchema(new AxArtifactKey("eventContextItem0", "0.0.1"), "Java",
+ "java.lang.String");
+ final AxContextSchema schema1 = new AxContextSchema(new AxArtifactKey("eventContextItem1", "0.0.1"), "Java",
+ "java.lang.Long");
+ final AxContextSchema schema2 = new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.policymodel.concepts.TestContextItem000");
+ final AxContextSchema schema3 = new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A");
+
+ final AxContextSchemas schemas = new AxContextSchemas(new AxArtifactKey("ContextSchemas", "0.0.1"));
+ schemas.getSchemasMap().put(schema0.getKey(), schema0);
+ schemas.getSchemasMap().put(schema1.getKey(), schema1);
+ schemas.getSchemasMap().put(schema2.getKey(), schema2);
+ schemas.getSchemasMap().put(schema3.getKey(), schema3);
+
+ final AxContextAlbum album0 = new AxContextAlbum(new AxArtifactKey("contextAlbum0", "0.0.1"), "APPLICATION",
+ true, schema3.getKey());
+ final AxContextAlbum album1 = new AxContextAlbum(new AxArtifactKey("contextAlbum1", "0.0.1"), "GLOBAL", false,
+ schema2.getKey());
+
+ final AxContextAlbums albums = new AxContextAlbums(new AxArtifactKey("context", "0.0.1"));
+ albums.getAlbumsMap().put(album0.getKey(), album0);
+ albums.getAlbumsMap().put(album1.getKey(), album1);
+
+ final AxEvent inEvent = new AxEvent(new AxArtifactKey("inEvent", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ inEvent.getParameterMap().put("IEPAR0",
+ new AxField(new AxReferenceKey(inEvent.getKey(), "IEPAR0"), schema0.getKey()));
+ inEvent.getParameterMap().put("IEPAR1",
+ new AxField(new AxReferenceKey(inEvent.getKey(), "IEPAR1"), schema1.getKey()));
+
+ final AxEvent outEvent0 = new AxEvent(new AxArtifactKey("outEvent0", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ outEvent0.getParameterMap().put("OE0PAR0",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE0PAR0"), schema0.getKey()));
+ outEvent0.getParameterMap().put("OE0PAR1",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE0PAR1"), schema1.getKey()));
+ outEvent0.getParameterMap().put("OE1PAR0",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE1PAR0"), schema0.getKey()));
+ outEvent0.getParameterMap().put("OE1PAR1",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE1PAR1"), schema1.getKey()));
+
+ final AxEvent outEvent1 = new AxEvent(new AxArtifactKey("outEvent1", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ outEvent1.getParameterMap().put("OE1PAR0",
+ new AxField(new AxReferenceKey(outEvent1.getKey(), "OE1PAR0"), schema0.getKey()));
+ outEvent1.getParameterMap().put("OE1PAR1",
+ new AxField(new AxReferenceKey(outEvent1.getKey(), "OE1PAR1"), schema1.getKey()));
+
+ final AxEvents events = new AxEvents(new AxArtifactKey("events", "0.0.1"));
+ events.getEventMap().put(inEvent.getKey(), inEvent);
+ events.getEventMap().put(outEvent0.getKey(), outEvent0);
+ events.getEventMap().put(outEvent1.getKey(), outEvent1);
+
+ final AxTask task = new AxTask(new AxArtifactKey("task", "0.0.1"));
+
+ task.setInputEvent(inEvent);
+ task.setOutputEvents(Map.of(outEvent0.getId(), outEvent0, outEvent1.getId(), outEvent1));
+
+ final AxTaskParameter taskPar0 = new AxTaskParameter(new AxReferenceKey(task.getKey(), "taskParameter0"),
+ "Task parameter 0 value");
+ final AxTaskParameter taskPar1 = new AxTaskParameter(new AxReferenceKey(task.getKey(), "taskParameter1"),
+ "Task parameter 1 value");
+
+ task.getTaskParameters().put(taskPar0.getKey().getLocalName(), taskPar0);
+ task.getTaskParameters().put(taskPar1.getKey().getLocalName(), taskPar1);
+ task.getContextAlbumReferences().add(album0.getKey());
+ task.getContextAlbumReferences().add(album1.getKey());
+
+ final AxTaskLogic taskLogic = new AxTaskLogic(new AxReferenceKey(task.getKey(), "taskLogic"), "MVEL",
+ "Some task logic");
+ task.setTaskLogic(taskLogic);
+
+ final AxTasks tasks = new AxTasks(new AxArtifactKey("tasks", "0.0.1"));
+ tasks.getTaskMap().put(task.getKey(), task);
+
+ final AxPolicy policy = new AxPolicy(new AxArtifactKey("policy", "0.0.1"));
+ policy.setTemplate("FREEFORM");
+
+ final AxState state = new AxState(new AxReferenceKey(policy.getKey(), "state"));
+ final AxTaskSelectionLogic taskSelectionLogic = new AxTaskSelectionLogic(
+ new AxReferenceKey(state.getKey(), "taskSelectionLogic"), "MVEL", "Some TS logic ");
+
+ state.setTrigger(inEvent.getKey());
+ state.getContextAlbumReferences().add(album0.getKey());
+ state.getContextAlbumReferences().add(album1.getKey());
+ state.setTaskSelectionLogic(taskSelectionLogic);
+ state.setDefaultTask(task.getKey());
+
+ final AxStateOutput stateOutput0 = new AxStateOutput(new AxReferenceKey(state.getKey(), "stateOutput0"),
+ outEvent0.getKey(), AxReferenceKey.getNullKey());
+ state.getStateOutputs().put(stateOutput0.getKey().getLocalName(), stateOutput0);
+
+ final AxStateTaskReference stateTaskReference = new AxStateTaskReference(
+ new AxReferenceKey(state.getKey(), task.getKey().getName()), AxStateTaskOutputType.DIRECT,
+ stateOutput0.getKey());
+
+ state.getTaskReferences().put(task.getKey(), stateTaskReference);
+
+ policy.getStateMap().put(state.getKey().getLocalName(), state);
+ policy.setFirstState(state.getKey().getLocalName());
+
+ final AxPolicies policies = new AxPolicies(new AxArtifactKey("policies", "0.0.1"));
+ policies.getPolicyMap().put(policy.getKey(), policy);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1"));
+ final AxPolicyModel policyModel = new AxPolicyModel(new AxArtifactKey("PolicyModel", "0.0.1"));
+ policyModel.setKeyInformation(keyInformation);
+ policyModel.setSchemas(schemas);
+ policyModel.setAlbums(albums);
+ policyModel.setEvents(events);
+ policyModel.setTasks(tasks);
+ policyModel.setPolicies(policies);
+ policyModel.getKeyInformation().generateKeyInfo(policyModel);
+
+ int uuidIncrementer = 0;
+ for (final AxKeyInfo keyInfo : policyModel.getKeyInformation().getKeyInfoMap().values()) {
+ final String uuidString = String.format("ce9168c-e6df-414f-9646-6da464b6e%03d", uuidIncrementer++);
+ keyInfo.setUuid(UUID.fromString(uuidString));
+ }
+
+ final AxValidationResult result = new AxValidationResult();
+ policyModel.validate(result);
+
+ return policyModel;
+ }
+
+ /**
+ * Gets another policy model.
+ *
+ * @return the model
+ */
+ public AxPolicyModel getAnotherModel() {
+ final AxContextSchema schema0 = new AxContextSchema(new AxArtifactKey("eventContextItemA0", "0.0.1"), "Java",
+ "java.lang.String");
+ final AxContextSchema schema1 = new AxContextSchema(new AxArtifactKey("eventContextItemA1", "0.0.1"), "Java",
+ "java.lang.Long");
+ final AxContextSchema schema2 = new AxContextSchema(new AxArtifactKey("StringTypeA", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.policymodel.concepts.TestContextItem000");
+ final AxContextSchema schema3 = new AxContextSchema(new AxArtifactKey("MapTypeA", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A");
+
+ final AxContextSchemas schemas = new AxContextSchemas(new AxArtifactKey("ContextSchemasA", "0.0.1"));
+ schemas.getSchemasMap().put(schema0.getKey(), schema0);
+ schemas.getSchemasMap().put(schema1.getKey(), schema1);
+ schemas.getSchemasMap().put(schema2.getKey(), schema2);
+ schemas.getSchemasMap().put(schema3.getKey(), schema3);
+
+ final AxContextAlbum album0 = new AxContextAlbum(new AxArtifactKey("contextAlbumA0", "0.0.1"), "APPLICATION",
+ true, schema3.getKey());
+ final AxContextAlbum album1 = new AxContextAlbum(new AxArtifactKey("contextAlbumA1", "0.0.1"), "GLOBAL", false,
+ schema2.getKey());
+
+ final AxContextAlbums albums = new AxContextAlbums(new AxArtifactKey("contextA", "0.0.1"));
+ albums.getAlbumsMap().put(album0.getKey(), album0);
+ albums.getAlbumsMap().put(album1.getKey(), album1);
+
+ final AxEvent inEvent = new AxEvent(new AxArtifactKey("inEventA", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ inEvent.getParameterMap().put("IEPARA0",
+ new AxField(new AxReferenceKey(inEvent.getKey(), "IEPARA0"), schema0.getKey()));
+ inEvent.getParameterMap().put("IEPARA1",
+ new AxField(new AxReferenceKey(inEvent.getKey(), "IEPARA1"), schema1.getKey()));
+
+ final AxEvent outEvent0 = new AxEvent(new AxArtifactKey("outEventA0", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ outEvent0.getParameterMap().put("OE0PARA0",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE0PARA0"), schema0.getKey()));
+ outEvent0.getParameterMap().put("OE0PARA1",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE0PARA1"), schema1.getKey()));
+ outEvent0.getParameterMap().put("OE1PARA0",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE1PARA0"), schema0.getKey()));
+ outEvent0.getParameterMap().put("OE1PARA1",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE1PARA1"), schema1.getKey()));
+
+ final AxEvent outEvent1 = new AxEvent(new AxArtifactKey("outEventA1", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ outEvent1.getParameterMap().put("OE1PARA0",
+ new AxField(new AxReferenceKey(outEvent1.getKey(), "OE1PARA0"), schema0.getKey()));
+ outEvent1.getParameterMap().put("OE1PARA1",
+ new AxField(new AxReferenceKey(outEvent1.getKey(), "OE1PARA1"), schema1.getKey()));
+
+ final AxEvents events = new AxEvents(new AxArtifactKey("eventsA", "0.0.1"));
+ events.getEventMap().put(inEvent.getKey(), inEvent);
+ events.getEventMap().put(outEvent0.getKey(), outEvent0);
+ events.getEventMap().put(outEvent1.getKey(), outEvent1);
+
+ final AxTask task = new AxTask(new AxArtifactKey("taskA", "0.0.1"));
+
+ task.setInputEvent(inEvent);
+ task.setOutputEvents(Map.of(outEvent0.getId(), outEvent0, outEvent1.getId(), outEvent1));
+
+ final AxTaskParameter taskPar0 = new AxTaskParameter(new AxReferenceKey(task.getKey(), "taskParameterA0"),
+ "Task parameter 0 value");
+ final AxTaskParameter taskPar1 = new AxTaskParameter(new AxReferenceKey(task.getKey(), "taskParameterA1"),
+ "Task parameter 1 value");
+
+ task.getTaskParameters().put(taskPar0.getKey().getLocalName(), taskPar0);
+ task.getTaskParameters().put(taskPar1.getKey().getLocalName(), taskPar1);
+ task.getContextAlbumReferences().add(album0.getKey());
+ task.getContextAlbumReferences().add(album1.getKey());
+
+ final AxTaskLogic taskLogic = new AxTaskLogic(new AxReferenceKey(task.getKey(), "taskLogicA"), "MVEL",
+ "Some task logic");
+ task.setTaskLogic(taskLogic);
+
+ final AxTasks tasks = new AxTasks(new AxArtifactKey("tasksA", "0.0.1"));
+ tasks.getTaskMap().put(task.getKey(), task);
+
+ final AxPolicy policy = new AxPolicy(new AxArtifactKey("policyA", "0.0.1"));
+ policy.setTemplate("FREEFORM");
+
+ final AxState state = new AxState(new AxReferenceKey(policy.getKey(), "stateA"));
+ final AxTaskSelectionLogic taskSelectionLogic = new AxTaskSelectionLogic(
+ new AxReferenceKey(state.getKey(), "taskSelectionLogicA"), "MVEL", "Some TS logic ");
+
+ state.setTrigger(inEvent.getKey());
+ state.getContextAlbumReferences().add(album0.getKey());
+ state.getContextAlbumReferences().add(album1.getKey());
+ state.setTaskSelectionLogic(taskSelectionLogic);
+ state.setDefaultTask(task.getKey());
+
+ final AxStateOutput stateOutput0 = new AxStateOutput(new AxReferenceKey(state.getKey(), "stateOutputA0"),
+ outEvent0.getKey(), AxReferenceKey.getNullKey());
+ state.getStateOutputs().put(stateOutput0.getKey().getLocalName(), stateOutput0);
+
+ final AxStateTaskReference stateTaskReference = new AxStateTaskReference(
+ new AxReferenceKey(state.getKey(), task.getKey().getName()), AxStateTaskOutputType.DIRECT,
+ stateOutput0.getKey());
+
+ state.getTaskReferences().put(task.getKey(), stateTaskReference);
+
+ policy.getStateMap().put(state.getKey().getLocalName(), state);
+ policy.setFirstState(state.getKey().getLocalName());
+
+ final AxPolicies policies = new AxPolicies(new AxArtifactKey("policiesA", "0.0.1"));
+ policies.getPolicyMap().put(policy.getKey(), policy);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKeyA", "0.0.1"));
+ final AxPolicyModel policyModel = new AxPolicyModel(new AxArtifactKey("PolicyModelA", "0.0.1"));
+ policyModel.setKeyInformation(keyInformation);
+ policyModel.setSchemas(schemas);
+ policyModel.setAlbums(albums);
+ policyModel.setEvents(events);
+ policyModel.setTasks(tasks);
+ policyModel.setPolicies(policies);
+ policyModel.getKeyInformation().generateKeyInfo(policyModel);
+
+ int uuidIncrementer = 0;
+ for (final AxKeyInfo keyInfo : policyModel.getKeyInformation().getKeyInfoMap().values()) {
+ final String uuidString = String.format("ce9168c-e6df-414f-9646-6da464b6e%03d", uuidIncrementer++);
+ keyInfo.setUuid(UUID.fromString(uuidString));
+ }
+
+ final AxValidationResult result = new AxValidationResult();
+ policyModel.validate(result);
+
+ return policyModel;
+ }
+
+ @Override
+ public AxPolicyModel getMalstructuredModel() {
+ final AxPolicyModel policyModel = new AxPolicyModel(new AxArtifactKey("policyModel", "0.0.1"));
+ return policyModel;
+ }
+
+ @Override
+ public AxPolicyModel getObservationModel() {
+ final AxPolicyModel policyModel = getModel();
+
+ final AxState state = policyModel.getPolicies().get("policy").getStateMap().get("state");
+ final AxTask task = policyModel.getTasks().get("task");
+
+ final AxStateFinalizerLogic stateFinalizerLogic = new AxStateFinalizerLogic(
+ new AxReferenceKey(state.getKey(), "SFL"), "MVEL", "Some SF logic ");
+ state.getStateFinalizerLogicMap().put(stateFinalizerLogic.getKey().getLocalName(), stateFinalizerLogic);
+ final AxStateTaskReference stateTaskReference = new AxStateTaskReference(
+ new AxReferenceKey(state.getKey(), task.getKey().getName()), AxStateTaskOutputType.LOGIC,
+ stateFinalizerLogic.getKey());
+
+ state.getTaskReferences().put(task.getKey(), stateTaskReference);
+
+ return policyModel;
+ }
+
+ @Override
+ public AxPolicyModel getWarningModel() {
+ final AxPolicyModel policyModel = getModel();
+
+ final AxState anotherState = new AxState(
+ new AxReferenceKey(new AxArtifactKey("policy", "0.0.1"), "anotherState"));
+
+ final AxEvent inEvent = policyModel.getEvents().getEventMap().get(new AxArtifactKey("inEvent", "0.0.1"));
+ final AxEvent outEvent0 = policyModel.getEvents().getEventMap().get(new AxArtifactKey("outEvent0", "0.0.1"));
+
+ final AxTask anotherTask = new AxTask(new AxArtifactKey("anotherTask", "0.0.1"));
+
+ anotherTask.setInputEvent(inEvent);
+ anotherTask.setOutputEvents(Map.of(outEvent0.getId(), outEvent0));
+ final AxTaskParameter taskPar0 = new AxTaskParameter(new AxReferenceKey(anotherTask.getKey(), "taskParameter0"),
+ "Task parameter 0 value");
+ final AxTaskParameter taskPar1 = new AxTaskParameter(new AxReferenceKey(anotherTask.getKey(), "taskParameter1"),
+ "Task parameter 1 value");
+
+ anotherTask.getTaskParameters().put(taskPar0.getKey().getLocalName(), taskPar0);
+ anotherTask.getTaskParameters().put(taskPar1.getKey().getLocalName(), taskPar1);
+
+ final AxTaskLogic taskLogic = new AxTaskLogic(new AxReferenceKey(anotherTask.getKey(), "taskLogic"), "MVEL",
+ "Some task logic");
+ anotherTask.setTaskLogic(taskLogic);
+ policyModel.getTasks().getTaskMap().put(anotherTask.getKey(), anotherTask);
+
+ final AxStateOutput anotherStateOutput0 = new AxStateOutput(
+ new AxReferenceKey(anotherState.getKey(), "stateOutput0"), outEvent0.getKey(),
+ AxReferenceKey.getNullKey());
+ anotherState.setTrigger(inEvent.getKey());
+ anotherState.getStateOutputs().put(anotherStateOutput0.getKey().getLocalName(), anotherStateOutput0);
+ anotherState.setDefaultTask(anotherTask.getKey());
+ final AxStateTaskReference anotherStateTaskReference = new AxStateTaskReference(
+ new AxReferenceKey(anotherState.getKey(), anotherTask.getKey().getName()),
+ AxStateTaskOutputType.DIRECT, anotherStateOutput0.getKey());
+ anotherState.getTaskReferences().put(anotherTask.getKey(), anotherStateTaskReference);
+
+ policyModel.getPolicies().getPolicyMap().get(new AxArtifactKey("policy", "0.0.1")).getStateMap()
+ .put(anotherState.getKey().getLocalName(), anotherState);
+
+ policyModel.getKeyInformation().generateKeyInfo(policyModel);
+
+ return policyModel;
+ }
+
+ @Override
+ public AxPolicyModel getInvalidModel() {
+ final AxPolicyModel policyModel = getModel();
+
+ policyModel.getAlbums().get(new AxArtifactKey("contextAlbum0", "0.0.1")).setScope("UNDEFINED");
+ policyModel.getAlbums().get(new AxArtifactKey("contextAlbum1", "0.0.1")).setScope("UNDEFINED");
+
+ final AxEvent outEvent0 = policyModel.getEvents().get("outEvent0");
+ outEvent0.getParameterMap().remove("OE1PAR0");
+ outEvent0.getParameterMap().remove("OE1PAR1");
+
+ return policyModel;
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/policymodel/utils/SupportPolicyModelValidator.java b/model/src/test/java/org/onap/policy/apex/model/policymodel/utils/SupportPolicyModelValidator.java
new file mode 100644
index 000000000..daff1efa7
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/policymodel/utils/SupportPolicyModelValidator.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.policymodel.utils;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+/**
+ * Main class to run the policy model validator.
+ */
+public class SupportPolicyModelValidator {
+ /**
+ * Main method.
+ * @param args the command line arguments
+ * @throws ApexModelException on errors on the apex model
+ * @throws FileNotFoundException on file find failures
+ */
+ public static void main(final String[] args) throws ApexModelException, FileNotFoundException {
+ final ApexModelReader<AxPolicyModel> policyModelReader = new ApexModelReader<AxPolicyModel>(
+ AxPolicyModel.class);
+
+ final AxPolicyModel policyModel = policyModelReader.read(new FileInputStream(args[0]));
+ final AxValidationResult result = policyModel.validate(new AxValidationResult());
+ System.out.println(result);
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/utilities/CollectionUtilitiesTest.java b/model/src/test/java/org/onap/policy/apex/model/utilities/CollectionUtilitiesTest.java
new file mode 100644
index 000000000..2512133e7
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/utilities/CollectionUtilitiesTest.java
@@ -0,0 +1,87 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+
+public class CollectionUtilitiesTest {
+
+ @Test
+ public void testNullLists() {
+ int result = 0;
+
+ result = CollectionUtils.compareLists(null, null);
+ assertEquals(0, result);
+
+ List<String> leftList = new ArrayList<String>();
+
+ result = CollectionUtils.compareLists(leftList, null);
+ assertEquals(-1, result);
+
+ List<String> rightList = new ArrayList<String>();
+
+ result = CollectionUtils.compareLists(null, rightList);
+ assertEquals(1, result);
+
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(0, result);
+
+ leftList.add("AAA");
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(-1, result);
+
+ rightList.add("AAA");
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(0, result);
+
+ rightList.add("BBB");
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(1, result);
+
+ leftList.add("BBB");
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(0, result);
+
+ leftList.add("CCA");
+ rightList.add("CCB");
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(-1, result);
+
+ leftList.remove(leftList.size() - 1);
+ rightList.remove(rightList.size() - 1);
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(0, result);
+
+ leftList.add("CCB");
+ rightList.add("CCA");
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(1, result);
+
+ leftList.remove(leftList.size() - 1);
+ rightList.remove(rightList.size() - 1);
+ result = CollectionUtils.compareLists(leftList, rightList);
+ assertEquals(0, result);
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/utilities/DirectoryUtilsTest.java b/model/src/test/java/org/onap/policy/apex/model/utilities/DirectoryUtilsTest.java
new file mode 100644
index 000000000..69c2d4763
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/utilities/DirectoryUtilsTest.java
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.utilities;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+import org.junit.Test;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+
+public class DirectoryUtilsTest {
+
+ @Test
+ public void test() throws IOException {
+ DirectoryUtils.emptyDirectory(new File("/i/dont/exist"));
+
+ File tempDir = Files.createTempDirectory("test").toFile();
+ assertNotNull(tempDir);
+
+ Files.createTempDirectory(tempDir.toPath(), "testsubprefix");
+
+ TextFileUtils.putStringAsTextFile("Temp File 0 contents", tempDir.getAbsolutePath() + "/tempFile0.tmp");
+ TextFileUtils.putStringAsTextFile("Temp File 1 contents", tempDir.getAbsolutePath() + "/tempFile1.tmp");
+
+ DirectoryUtils.emptyDirectory(tempDir);
+
+ DirectoryUtils.getLocalTempDirectory(null);
+
+ byte[] byteArray = new byte[] {0, 0, 0};
+ DirectoryUtils.getLocalTempDirectory(Arrays.toString(byteArray));
+ }
+
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/utilities/KeyComparerTest.java b/model/src/test/java/org/onap/policy/apex/model/utilities/KeyComparerTest.java
new file mode 100644
index 000000000..20780b271
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/utilities/KeyComparerTest.java
@@ -0,0 +1,53 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.utilities;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.utilities.comparison.KeyComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyDifference;
+
+/**
+ * Test key comparisons.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class KeyComparerTest {
+
+ @Test
+ public void test() {
+ KeyDifference<String> keyDifference = new KeyComparer<String>().compareKeys("Hello", "Goodbye");
+
+ assertFalse(keyDifference.isEqual());
+ assertEquals("Hello", keyDifference.getLeftKey().toString());
+ assertEquals("Goodbye", keyDifference.getRightKey().toString());
+
+ assertEquals("left key Hello and right key Goodbye differ\n", keyDifference.asString(true));
+ assertEquals("left key Hello and right key Goodbye differ\n", keyDifference.asString(false));
+
+ KeyDifference<String> keyDifference2 = new KeyComparer<String>().compareKeys("Here", "Here");
+ assertEquals("", keyDifference2.asString(true));
+ assertEquals("left key Here equals right key Here\n", keyDifference2.asString(false));
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/utilities/KeyedMapComparerTest.java b/model/src/test/java/org/onap/policy/apex/model/utilities/KeyedMapComparerTest.java
new file mode 100644
index 000000000..b4e88e20d
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/utilities/KeyedMapComparerTest.java
@@ -0,0 +1,76 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.utilities;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.TreeMap;
+import org.junit.Test;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference;
+
+/**
+ * Test key map comparisons.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class KeyedMapComparerTest {
+
+ @Test
+ public void test() {
+ TreeMap<String, String> leftMap = new TreeMap<String, String>();
+ leftMap.put("B", "BBBBB");
+ leftMap.put("C", "CCCCC");
+ leftMap.put("E", "EEEEE");
+ leftMap.put("G", "GGGGG");
+
+ TreeMap<String, String> rightMap = new TreeMap<String, String>();
+ rightMap.put("A", "AAAAA");
+ rightMap.put("B", "B");
+ rightMap.put("D", "DDDDD");
+ rightMap.put("E", "EEEEE");
+ rightMap.put("F", "FFFFF");
+ rightMap.put("G", "G");
+
+ KeyedMapDifference<String, String> kmComparedSame =
+ new KeyedMapComparer<String, String>().compareMaps(leftMap, leftMap);
+ KeyedMapDifference<String, String> kmComparedDiff =
+ new KeyedMapComparer<String, String>().compareMaps(leftMap, rightMap);
+
+ assertEquals(leftMap, kmComparedSame.getIdenticalValues());
+ assertEquals(1, kmComparedDiff.getLeftOnly().size());
+ assertEquals(3, kmComparedDiff.getRightOnly().size());
+ assertEquals(2, kmComparedDiff.getDifferentValues().size());
+ assertEquals(1, kmComparedDiff.getIdenticalValues().size());
+
+ assertNotNull(kmComparedSame.asString(true, true));
+ assertNotNull(kmComparedSame.asString(true, false));
+ assertNotNull(kmComparedSame.asString(false, false));
+ assertNotNull(kmComparedSame.asString(false, true));
+
+ assertNotNull(kmComparedDiff.asString(true, true));
+ assertNotNull(kmComparedDiff.asString(true, false));
+ assertNotNull(kmComparedDiff.asString(false, false));
+ assertNotNull(kmComparedDiff.asString(false, true));
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/utilities/TextFileUtilsTest.java b/model/src/test/java/org/onap/policy/apex/model/utilities/TextFileUtilsTest.java
new file mode 100644
index 000000000..1d6f29fe5
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/utilities/TextFileUtilsTest.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 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.onap.policy.apex.model.utilities;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import org.junit.Test;
+import org.onap.policy.common.utils.resources.TextFileUtils;
+
+/**
+ * Test text file utilities.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TextFileUtilsTest {
+
+ private static final String FILE_CONTENT = "This is the contents of a text file";
+
+ @Test
+ public void test() throws IOException {
+ final File tempTextFile = File.createTempFile("Test", "txt");
+
+ TextFileUtils.putStringAsTextFile(FILE_CONTENT, tempTextFile.getAbsolutePath());
+
+ final String textFileString0 = TextFileUtils.getTextFileAsString(tempTextFile.getAbsolutePath());
+ assertEquals(FILE_CONTENT, textFileString0);
+
+ final FileInputStream fis = new FileInputStream(tempTextFile);
+ final String textFileString1 = TextFileUtils.getStreamAsString(fis);
+ assertEquals(textFileString0, textFileString1);
+
+ }
+
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/utilities/TreeMapUtilsTest.java b/model/src/test/java/org/onap/policy/apex/model/utilities/TreeMapUtilsTest.java
new file mode 100644
index 000000000..c3a36b7b9
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/utilities/TreeMapUtilsTest.java
@@ -0,0 +1,157 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import org.junit.Test;
+
+/**
+ * Test the tree map utilities.
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TreeMapUtilsTest {
+
+ private static final int KEY1 = 10;
+ private static final int KEY2 = 20;
+ private static final int KEY3 = 30;
+ private static final String VALUE1 = "a-one";
+ private static final String VALUE2 = "b-two";
+ private static final String VALUE3 = "c-three";
+ private static final String VALUE4 = "d-four";
+
+ @Test
+ public void testFindMatchingEntries() {
+ TreeMap<String, String> testTreeMap = new TreeMap<String, String>();
+ testTreeMap.put("G", "G");
+ testTreeMap.put("H", "H");
+ testTreeMap.put("JA", "JA");
+ testTreeMap.put("JAM", "JAM");
+ testTreeMap.put("JOE", "JOE");
+ testTreeMap.put("JOSH", "JOSH");
+ testTreeMap.put("K", "K");
+
+ List<Entry<String, String>> foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "F");
+ assertEquals(0, foundKeyList.size());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "G");
+ assertEquals("G", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "H");
+ assertEquals("H", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "I");
+ assertEquals(0, foundKeyList.size());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "J");
+ assertEquals("JA", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "JA");
+ assertEquals("JA", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "JB");
+ assertEquals(0, foundKeyList.size());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "JO");
+ assertEquals("JOE", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "JOE");
+ assertEquals("JOE", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "JOS");
+ assertEquals("JOSH", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "JOSH");
+ assertEquals("JOSH", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "K");
+ assertEquals("K", foundKeyList.get(0).getKey());
+
+ foundKeyList = TreeMapUtils.findMatchingEntries(testTreeMap, "L");
+ assertEquals(0, foundKeyList.size());
+ }
+
+ @Test
+ public void testCompareMaps() {
+ Map<Integer, String> map1 = Map.of();
+ Map<Integer, String> map2 = Map.of();
+
+ // note: using TreeMap so we can control the ordering of the entries
+
+ // compare with self
+ assertThat(TreeMapUtils.compareMaps(map1, map1)).isZero();
+
+ // two empty maps
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isZero();
+
+ // same content
+ map1 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2, KEY3, VALUE3));
+ map2 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2, KEY3, VALUE3));
+ assertThat(TreeMapUtils.compareMaps(map1, map1)).isZero();
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isZero();
+
+ // one is shorter than the other
+ map1 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2, KEY3, VALUE3));
+ map2 = new TreeMap<>(Map.of(KEY1, VALUE1));
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isPositive();
+ assertThat(TreeMapUtils.compareMaps(map2, map1)).isNegative();
+
+ map2 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2));
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isPositive();
+ assertThat(TreeMapUtils.compareMaps(map2, map1)).isNegative();
+
+ // first key is different
+ map1 = new TreeMap<>(Map.of(KEY3, VALUE1, KEY2, VALUE2));
+ map2 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2));
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isPositive();
+ assertThat(TreeMapUtils.compareMaps(map2, map1)).isNegative();
+
+ // second key is different
+ map1 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY3, VALUE2));
+ map2 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2));
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isPositive();
+ assertThat(TreeMapUtils.compareMaps(map2, map1)).isNegative();
+
+ // first value is different
+ map1 = new TreeMap<>(Map.of(KEY1, VALUE4, KEY2, VALUE2, KEY3, VALUE3));
+ map2 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2, KEY3, VALUE3));
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isPositive();
+ assertThat(TreeMapUtils.compareMaps(map2, map1)).isNegative();
+
+ // second value is different
+ map1 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE4, KEY3, VALUE3));
+ map2 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2, KEY3, VALUE3));
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isPositive();
+ assertThat(TreeMapUtils.compareMaps(map2, map1)).isNegative();
+
+ // third value is different
+ map1 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2, KEY3, VALUE4));
+ map2 = new TreeMap<>(Map.of(KEY1, VALUE1, KEY2, VALUE2, KEY3, VALUE3));
+ assertThat(TreeMapUtils.compareMaps(map1, map2)).isPositive();
+ assertThat(TreeMapUtils.compareMaps(map2, map1)).isNegative();
+ }
+}
diff --git a/model/src/test/java/org/onap/policy/apex/model/utilities/json/JsonHandlerTest.java b/model/src/test/java/org/onap/policy/apex/model/utilities/json/JsonHandlerTest.java
new file mode 100644
index 000000000..ae5d53ec3
--- /dev/null
+++ b/model/src/test/java/org/onap/policy/apex/model/utilities/json/JsonHandlerTest.java
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.onap.policy.apex.model.utilities.json;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.gson.GsonBuilder;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import org.junit.Test;
+
+public class JsonHandlerTest {
+
+ private static final String VALUE = "value";
+
+ @Test
+ public void testAssertions() throws IOException {
+ final OverTheMoonObject jsonObject = new OverTheMoonObject(VALUE);
+ final String jsonString = new GsonBuilder().create().toJson(jsonObject);
+
+ final byte[] bytes = jsonString.getBytes(StandardCharsets.UTF_8);
+ try (final InputStream inputStream = new ByteArrayInputStream(bytes);) {
+
+ final JsonHandler<OverTheMoonObject> objUnderTest = new JsonHandler<>();
+
+ final OverTheMoonObject actualObject = objUnderTest.read(OverTheMoonObject.class, inputStream);
+ assertEquals(VALUE, actualObject.name);
+ }
+
+ }
+
+ private class OverTheMoonObject {
+ private final String name;
+
+ public OverTheMoonObject(final String name) {
+ this.name = name;
+ }
+ }
+}
diff --git a/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt b/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt
new file mode 100644
index 000000000..4d00394b7
--- /dev/null
+++ b/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt
@@ -0,0 +1,12 @@
+****** policy map differences ******
+*** context schema differences ***
+*** event differences ***
+*** context album differences ***
+*** task differences ***
+*** policy differences ***
+*** key information differences ***
+*** list of keys on left only
+key=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1)
+*** list of keys on right only
+key=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1)
+***********************************
diff --git a/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt b/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt
new file mode 100644
index 000000000..82fecd990
--- /dev/null
+++ b/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt
@@ -0,0 +1,12 @@
+****** policy map differences ******
+*** context schema differences ***
+*** event differences ***
+*** context album differences ***
+*** task differences ***
+*** policy differences ***
+*** key information differences ***
+*** list of keys on left only
+key=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6f000,description=Left only key info)
+*** list of keys on right only
+key=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6f001,description=Right only key info)
+***********************************
diff --git a/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt b/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt
new file mode 100644
index 000000000..38623c32a
--- /dev/null
+++ b/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt
@@ -0,0 +1,70 @@
+****** policy map differences ******
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** context schema differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=MapType,version=0.0.1)
+key=AxArtifactKey:(name=StringType,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1)
+*** event differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1)
+*** context album differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1)
+*** task differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=task,version=0.0.1)
+*** policy differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=policy,version=0.0.1)
+*** key information differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** list of keys on left only
+key=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1)
+*** list of keys on right only
+key=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1)
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=ContextSchemas,version=0.0.1)
+key=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1)
+key=AxArtifactKey:(name=MapType,version=0.0.1)
+key=AxArtifactKey:(name=PolicyModel,version=0.0.1)
+key=AxArtifactKey:(name=StringType,version=0.0.1)
+key=AxArtifactKey:(name=context,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1)
+key=AxArtifactKey:(name=events,version=0.0.1)
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1)
+key=AxArtifactKey:(name=policies,version=0.0.1)
+key=AxArtifactKey:(name=policy,version=0.0.1)
+key=AxArtifactKey:(name=task,version=0.0.1)
+key=AxArtifactKey:(name=tasks,version=0.0.1)
+*********************************** \ No newline at end of file
diff --git a/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt b/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt
new file mode 100644
index 000000000..53cadd979
--- /dev/null
+++ b/model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt
@@ -0,0 +1,70 @@
+****** policy map differences ******
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** context schema differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=MapType,version=0.0.1),value=AxContextSchema(key=AxArtifactKey:(name=MapType,version=0.0.1), schemaFlavour=Java, schemaDefinition=org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A)
+key=AxArtifactKey:(name=StringType,version=0.0.1),value=AxContextSchema(key=AxArtifactKey:(name=StringType,version=0.0.1), schemaFlavour=Java, schemaDefinition=org.onap.policy.apex.model.policymodel.concepts.TestContextItem000)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),value=AxContextSchema(key=AxArtifactKey:(name=eventContextItem0,version=0.0.1), schemaFlavour=Java, schemaDefinition=java.lang.String)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),value=AxContextSchema(key=AxArtifactKey:(name=eventContextItem1,version=0.0.1), schemaFlavour=Java, schemaDefinition=java.lang.Long)
+*** event differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=inEvent,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={IEPAR0=AxField:(key=AxReferenceKey:(parentKeyName=inEvent,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=IEPAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), IEPAR1=AxField:(key=AxReferenceKey:(parentKeyName=inEvent,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=IEPAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},toscaPolicyState=)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=outEvent0,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={OE0PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE0PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE0PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE0PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false), OE1PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},toscaPolicyState=)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=outEvent1,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={OE1PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},toscaPolicyState=)
+*** context album differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),value=AxContextAlbum(key=AxArtifactKey:(name=contextAlbum0,version=0.0.1), scope=APPLICATION, isWritable=true, itemSchema=AxArtifactKey:(name=MapType,version=0.0.1))
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),value=AxContextAlbum(key=AxArtifactKey:(name=contextAlbum1,version=0.0.1), scope=GLOBAL, isWritable=false, itemSchema=AxArtifactKey:(name=StringType,version=0.0.1))
+*** task differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=task,version=0.0.1),value=AxTask:(key=AxArtifactKey:(name=task,version=0.0.1),taskParameters={taskParameter0=AxTaskParameter:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskParameter0),defaultValue=Task parameter 0 value), taskParameter1=AxTaskParameter:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskParameter1),defaultValue=Task parameter 1 value)},contextAlbumReferenceSet=[AxArtifactKey:(name=contextAlbum0,version=0.0.1), AxArtifactKey:(name=contextAlbum1,version=0.0.1)],taskLogic=AxTaskLogic:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskLogic),logicFlavour=MVEL,logic=Some task logic))
+*** policy differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=policy,version=0.0.1),value=AxPolicy:(key=AxArtifactKey:(name=policy,version=0.0.1),template=FREEFORM,stateMap={state=AxState:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=state),trigger=AxArtifactKey:(name=inEvent,version=0.0.1),stateOutputs={stateOutput0=AxStateOutput:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=stateOutput0),outgoingEvent=AxArtifactKey:(name=outEvent0,version=0.0.1),nextState=AxReferenceKey:(parentKeyName=NULL,parentKeyVersion=0.0.0,parentLocalName=NULL,localName=NULL))},contextAlbumReferenceSet=[AxArtifactKey:(name=contextAlbum0,version=0.0.1), AxArtifactKey:(name=contextAlbum1,version=0.0.1)],taskSelectionLogic=AxTaskSelectionLogic:(key=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=taskSelectionLogic),logicFlavour=MVEL,logic=Some TS logic),stateFinalizerLogicSet={},defaultTask=AxArtifactKey:(name=task,version=0.0.1),taskReferenceMap={AxArtifactKey:(name=task,version=0.0.1)=AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=task),outputType=DIRECT,output=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=stateOutput0))})},firstState=state)
+*** key information differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** list of keys on left only
+key=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6f000,description=Left only key info)
+*** list of keys on right only
+key=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6f001,description=Right only key info)
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=ContextSchemas,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=ContextSchemas,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e000,description=Generated description for concept referred to by key "ContextSchemas:0.0.1")
+key=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e001,description=Generated description for concept referred to by key "KeyInfoMapKey:0.0.1")
+key=AxArtifactKey:(name=MapType,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=MapType,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e002,description=Generated description for concept referred to by key "MapType:0.0.1")
+key=AxArtifactKey:(name=PolicyModel,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=PolicyModel,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e003,description=Generated description for concept referred to by key "PolicyModel:0.0.1")
+key=AxArtifactKey:(name=StringType,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=StringType,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e004,description=Generated description for concept referred to by key "StringType:0.0.1")
+key=AxArtifactKey:(name=context,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=context,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e005,description=Generated description for concept referred to by key "context:0.0.1")
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=contextAlbum0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e006,description=Generated description for concept referred to by key "contextAlbum0:0.0.1")
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=contextAlbum1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e007,description=Generated description for concept referred to by key "contextAlbum1:0.0.1")
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=eventContextItem0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e008,description=Generated description for concept referred to by key "eventContextItem0:0.0.1")
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=eventContextItem1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e009,description=Generated description for concept referred to by key "eventContextItem1:0.0.1")
+key=AxArtifactKey:(name=events,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=events,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e010,description=Generated description for concept referred to by key "events:0.0.1")
+key=AxArtifactKey:(name=inEvent,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=inEvent,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e011,description=Left InEvent Description)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=outEvent0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e012,description=Generated description for concept referred to by key "outEvent0:0.0.1")
+key=AxArtifactKey:(name=outEvent1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=outEvent1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e013,description=Generated description for concept referred to by key "outEvent1:0.0.1")
+key=AxArtifactKey:(name=policies,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=policies,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e014,description=Generated description for concept referred to by key "policies:0.0.1")
+key=AxArtifactKey:(name=policy,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=policy,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e015,description=Generated description for concept referred to by key "policy:0.0.1")
+key=AxArtifactKey:(name=task,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=task,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e016,description=Generated description for concept referred to by key "task:0.0.1")
+key=AxArtifactKey:(name=tasks,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=tasks,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e017,description=Generated description for concept referred to by key "tasks:0.0.1")
+*********************************** \ No newline at end of file
diff --git a/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt b/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt
new file mode 100644
index 000000000..b9c0decdd
--- /dev/null
+++ b/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt
@@ -0,0 +1,8 @@
+****** policy map differences ******
+*** context schema differences ***
+*** event differences ***
+*** context album differences ***
+*** task differences ***
+*** policy differences ***
+*** key information differences ***
+*********************************** \ No newline at end of file
diff --git a/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt b/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt
new file mode 100644
index 000000000..17862e1b1
--- /dev/null
+++ b/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt
@@ -0,0 +1,69 @@
+****** policy map differences ******
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** context schema differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=MapType,version=0.0.1)
+key=AxArtifactKey:(name=StringType,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1)
+*** event differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1)
+*** context album differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1)
+*** task differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=task,version=0.0.1)
+*** policy differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=policy,version=0.0.1)
+*** key information differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=ContextSchemas,version=0.0.1)
+key=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1)
+key=AxArtifactKey:(name=MapType,version=0.0.1)
+key=AxArtifactKey:(name=PolicyModel,version=0.0.1)
+key=AxArtifactKey:(name=StringType,version=0.0.1)
+key=AxArtifactKey:(name=context,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1)
+key=AxArtifactKey:(name=events,version=0.0.1)
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1)
+key=AxArtifactKey:(name=policies,version=0.0.1)
+key=AxArtifactKey:(name=policy,version=0.0.1)
+key=AxArtifactKey:(name=task,version=0.0.1)
+key=AxArtifactKey:(name=tasks,version=0.0.1)
+***********************************
+
diff --git a/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt b/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt
new file mode 100644
index 000000000..4e07c5360
--- /dev/null
+++ b/model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt
@@ -0,0 +1,68 @@
+****** policy map differences ******
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** context schema differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=MapType,version=0.0.1),value=AxContextSchema(key=AxArtifactKey:(name=MapType,version=0.0.1),schemaFlavour=Java,schemaDefinition=org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A)
+key=AxArtifactKey:(name=StringType,version=0.0.1),value=AxContextSchema(key=AxArtifactKey:(name=StringType,version=0.0.1),schemaFlavour=Java,schemaDefinition=org.onap.policy.apex.model.policymodel.concepts.TestContextItem000)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),value=AxContextSchema(key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),schemaFlavour=Java,schemaDefinition=java.lang.String)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),value=AxContextSchema(key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),schemaFlavour=Java,schemaDefinition=java.lang.Long)
+*** event differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=inEvent,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={IEPAR0=AxField:(key=AxReferenceKey:(parentKeyName=inEvent,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=IEPAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), IEPAR1=AxField:(key=AxReferenceKey:(parentKeyName=inEvent,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=IEPAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},toscaPolicyState=)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=outEvent0,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={OE0PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE0PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE0PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE0PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false), OE1PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},toscaPolicyState=)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=outEvent1,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={OE1PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},toscaPolicyState=)
+*** context album differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),value=AxContextAlbum(key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),scope=APPLICATION,isWritable=true,itemSchema=AxArtifactKey:(name=MapType,version=0.0.1))
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),value=AxContextAlbum(key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),scope=GLOBAL,isWritable=false,itemSchema=AxArtifactKey:(name=StringType,version=0.0.1))
+*** task differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=task,version=0.0.1),value=AxTask:(key=AxArtifactKey:(name=task,version=0.0.1),taskParameters={taskParameter0=AxTaskParameter:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskParameter0),defaultValue=Task parameter 0 value), taskParameter1=AxTaskParameter:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskParameter1),defaultValue=Task parameter 1 value)},contextAlbumReferenceSet=[AxArtifactKey:(name=contextAlbum0,version=0.0.1), AxArtifactKey:(name=contextAlbum1,version=0.0.1)],taskLogic=AxTaskLogic:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskLogic),logicFlavour=MVEL,logic=Some task logic))
+*** policy differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=policy,version=0.0.1),value=AxPolicy:(key=AxArtifactKey:(name=policy,version=0.0.1),template=FREEFORM,stateMap={state=AxState:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=state),trigger=AxArtifactKey:(name=inEvent,version=0.0.1),stateOutputs={stateOutput0=AxStateOutput:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=stateOutput0),outgoingEvent=AxArtifactKey:(name=outEvent0,version=0.0.1),nextState=AxReferenceKey:(parentKeyName=NULL,parentKeyVersion=0.0.0,parentLocalName=NULL,localName=NULL))},contextAlbumReferenceSet=[AxArtifactKey:(name=contextAlbum0,version=0.0.1), AxArtifactKey:(name=contextAlbum1,version=0.0.1)],taskSelectionLogic=AxTaskSelectionLogic:(key=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=taskSelectionLogic),logicFlavour=MVEL,logic=Some TS logic),stateFinalizerLogicSet={},defaultTask=AxArtifactKey:(name=task,version=0.0.1),taskReferenceMap={AxArtifactKey:(name=task,version=0.0.1)=AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=task),outputType=DIRECT,output=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=stateOutput0))})},firstState=state)
+*** key information differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=ContextSchemas,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=ContextSchemas,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e000,description=Generated description for concept referred to by key "ContextSchemas:0.0.1")
+key=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e001,description=Generated description for concept referred to by key "KeyInfoMapKey:0.0.1")
+key=AxArtifactKey:(name=MapType,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=MapType,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e002,description=Generated description for concept referred to by key "MapType:0.0.1")
+key=AxArtifactKey:(name=PolicyModel,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=PolicyModel,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e003,description=Generated description for concept referred to by key "PolicyModel:0.0.1")
+key=AxArtifactKey:(name=StringType,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=StringType,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e004,description=Generated description for concept referred to by key "StringType:0.0.1")
+key=AxArtifactKey:(name=context,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=context,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e005,description=Generated description for concept referred to by key "context:0.0.1")
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=contextAlbum0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e006,description=Generated description for concept referred to by key "contextAlbum0:0.0.1")
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=contextAlbum1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e007,description=Generated description for concept referred to by key "contextAlbum1:0.0.1")
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=eventContextItem0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e008,description=Generated description for concept referred to by key "eventContextItem0:0.0.1")
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=eventContextItem1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e009,description=Generated description for concept referred to by key "eventContextItem1:0.0.1")
+key=AxArtifactKey:(name=events,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=events,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e010,description=Generated description for concept referred to by key "events:0.0.1")
+key=AxArtifactKey:(name=inEvent,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=inEvent,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e011,description=Generated description for concept referred to by key "inEvent:0.0.1")
+key=AxArtifactKey:(name=outEvent0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=outEvent0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e012,description=Generated description for concept referred to by key "outEvent0:0.0.1")
+key=AxArtifactKey:(name=outEvent1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=outEvent1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e013,description=Generated description for concept referred to by key "outEvent1:0.0.1")
+key=AxArtifactKey:(name=policies,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=policies,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e014,description=Generated description for concept referred to by key "policies:0.0.1")
+key=AxArtifactKey:(name=policy,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=policy,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e015,description=Generated description for concept referred to by key "policy:0.0.1")
+key=AxArtifactKey:(name=task,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=task,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e016,description=Generated description for concept referred to by key "task:0.0.1")
+key=AxArtifactKey:(name=tasks,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=tasks,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e017,description=Generated description for concept referred to by key "tasks:0.0.1")
+*********************************** \ No newline at end of file
diff --git a/model/src/test/resources/logback-test.xml b/model/src/test/resources/logback-test.xml
new file mode 100644
index 000000000..af4993550
--- /dev/null
+++ b/model/src/test/resources/logback-test.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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=========================================================
+-->
+
+<configuration>
+
+ <contextName>Apex</contextName>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+ <property name="LOG_DIR" value="${java.io.tmpdir}/apex_logging/" />
+
+ <!-- USE FOR STD OUT ONLY -->
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <root level="INFO">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+ <logger name="org.infinispan" level="INFO" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="org.onap.policy.apex.core.contextmodel" level="INFO" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="org.apache.zookeeper.ClientCnxn" level="OFF" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="org.onap.policy.apex.core" level="INFO" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${LOG_DIR}/apex.log</file>
+ <encoder>
+ <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+ %logger{26} - %msg %n %ex{full}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="CTXT_FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${LOG_DIR}/apex_ctxt.log</file>
+ <encoder>
+ <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+ %logger{26} - %msg %n %ex{full}</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="org.onap.policy.apex.core.context.impl.monitoring" level="INFO" additivity="false">
+ <appender-ref ref="CTXT_FILE" />
+ </logger>
+
+ <logger name="org.onap.policy.apex.core.context" level="INFO" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+</configuration>
diff --git a/model/src/test/resources/models/PolicyModel.json b/model/src/test/resources/models/PolicyModel.json
new file mode 100644
index 000000000..fbb91bb0b
--- /dev/null
+++ b/model/src/test/resources/models/PolicyModel.json
@@ -0,0 +1,775 @@
+{
+ "key": {
+ "name": "PolicyModel",
+ "version": "0.0.1"
+ },
+ "keyInformation": {
+ "key": {
+ "name": "KeyInfoMapKey",
+ "version": "0.0.1"
+ },
+ "keyInfoMap": {
+ "entry": [
+ {
+ "key": {
+ "name": "ContextSchemas",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ContextSchemas",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e000",
+ "description": "Generated description for concept referred to by key \"ContextSchemas:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "KeyInfoMapKey",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "KeyInfoMapKey",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e001",
+ "description": "Generated description for concept referred to by key \"KeyInfoMapKey:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "MapType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "MapType",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e002",
+ "description": "Generated description for concept referred to by key \"MapType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "PolicyModel",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "PolicyModel",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e003",
+ "description": "Generated description for concept referred to by key \"PolicyModel:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "StringType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "StringType",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e004",
+ "description": "Generated description for concept referred to by key \"StringType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "context",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "context",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e005",
+ "description": "Generated description for concept referred to by key \"context:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "contextAlbum0",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "contextAlbum0",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e006",
+ "description": "Generated description for concept referred to by key \"contextAlbum0:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "contextAlbum1",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "contextAlbum1",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e007",
+ "description": "Generated description for concept referred to by key \"contextAlbum1:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e008",
+ "description": "Generated description for concept referred to by key \"eventContextItem0:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e009",
+ "description": "Generated description for concept referred to by key \"eventContextItem1:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "events",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "events",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e010",
+ "description": "Generated description for concept referred to by key \"events:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "inEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "inEvent",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e011",
+ "description": "Generated description for concept referred to by key \"inEvent:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "outEvent0",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "outEvent0",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e012",
+ "description": "Generated description for concept referred to by key \"outEvent0:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "outEvent1",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "outEvent1",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e013",
+ "description": "Generated description for concept referred to by key \"outEvent1:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "policies",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "policies",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e014",
+ "description": "Generated description for concept referred to by key \"policies:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "policy",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "policy",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e015",
+ "description": "Generated description for concept referred to by key \"policy:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "task",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "task",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e016",
+ "description": "Generated description for concept referred to by key \"task:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "tasks",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "tasks",
+ "version": "0.0.1"
+ },
+ "UUID": "0ce9168c-e6df-414f-9646-6da464b6e017",
+ "description": "Generated description for concept referred to by key \"tasks:0.0.1\""
+ }
+ }
+ ]
+ }
+ },
+ "policies": {
+ "key": {
+ "name": "policies",
+ "version": "0.0.1"
+ },
+ "policyMap": {
+ "entry": [
+ {
+ "key": {
+ "name": "policy",
+ "version": "0.0.1"
+ },
+ "value": {
+ "policyKey": {
+ "name": "policy",
+ "version": "0.0.1"
+ },
+ "template": "FREEFORM",
+ "state": {
+ "entry": [
+ {
+ "key": "state",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "policy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "state"
+ },
+ "trigger": {
+ "name": "inEvent",
+ "version": "0.0.1"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "stateOutput0",
+ "value": {
+ "key": {
+ "parentKeyName": "policy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "state",
+ "localName": "stateOutput0"
+ },
+ "outgoingEvent": {
+ "name": "outEvent0",
+ "version": "0.0.1"
+ },
+ "nextState": {
+ "parentKeyName": "NULL",
+ "parentKeyVersion": "0.0.0",
+ "parentLocalName": "NULL",
+ "localName": "NULL"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [
+ {
+ "name": "contextAlbum0",
+ "version": "0.0.1"
+ },
+ {
+ "name": "contextAlbum1",
+ "version": "0.0.1"
+ }
+ ],
+ "taskSelectionLogic": {
+ "key": "taskSelectionLogic",
+ "logicFlavour": "MVEL",
+ "logic": "Some TS logic"
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "task",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "task",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "policy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "state",
+ "localName": "task"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "policy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "state",
+ "localName": "stateOutput0"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "firstState": "state"
+ }
+ }
+ ]
+ }
+ },
+ "tasks": {
+ "key": {
+ "name": "tasks",
+ "version": "0.0.1"
+ },
+ "taskMap": {
+ "entry": [
+ {
+ "key": {
+ "name": "task",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "task",
+ "version": "0.0.1"
+ },
+ "inputFields": {
+ "entry": [
+ {
+ "key": "IEPAR0",
+ "value": {
+ "key": "IEPAR0",
+ "fieldSchemaKey": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "IEPAR1",
+ "value": {
+ "key": "IEPAR1",
+ "fieldSchemaKey": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ }
+ }
+ }
+ ]
+ },
+ "outputFields": {
+ "entry": [
+ {
+ "key": "OE0PAR0",
+ "value": {
+ "key": "OE0PAR0",
+ "fieldSchemaKey": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "OE0PAR1",
+ "value": {
+ "key": "OE0PAR1",
+ "fieldSchemaKey": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "OE1PAR0",
+ "value": {
+ "key": "OE1PAR0",
+ "fieldSchemaKey": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "OE1PAR1",
+ "value": {
+ "key": "OE1PAR1",
+ "fieldSchemaKey": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ }
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": [
+ {
+ "key": "taskParameter0",
+ "value": {
+ "key": {
+ "parentKeyName": "task",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "taskParameter0"
+ },
+ "defaultValue": "Task parameter 0 value"
+ }
+ },
+ {
+ "key": "taskParameter1",
+ "value": {
+ "key": {
+ "parentKeyName": "task",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "taskParameter1"
+ },
+ "defaultValue": "Task parameter 1 value"
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [
+ {
+ "name": "contextAlbum0",
+ "version": "0.0.1"
+ },
+ {
+ "name": "contextAlbum1",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "taskLogic",
+ "logicFlavour": "MVEL",
+ "logic": "Some task logic"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "events": {
+ "key": {
+ "name": "events",
+ "version": "0.0.1"
+ },
+ "eventMap": {
+ "entry": [
+ {
+ "key": {
+ "name": "inEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "inEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.model.policymodel.events",
+ "source": "Source",
+ "target": "Target",
+ "parameter": {
+ "entry": [
+ {
+ "key": "IEPAR0",
+ "value": {
+ "key": "IEPAR0",
+ "fieldSchemaKey": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "IEPAR1",
+ "value": {
+ "key": "IEPAR1",
+ "fieldSchemaKey": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "outEvent0",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "outEvent0",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.model.policymodel.events",
+ "source": "Source",
+ "target": "Target",
+ "parameter": {
+ "entry": [
+ {
+ "key": "OE0PAR0",
+ "value": {
+ "key": "OE0PAR0",
+ "fieldSchemaKey": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "OE0PAR1",
+ "value": {
+ "key": "OE0PAR1",
+ "fieldSchemaKey": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "OE1PAR0",
+ "value": {
+ "key": "OE1PAR0",
+ "fieldSchemaKey": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "OE1PAR1",
+ "value": {
+ "key": "OE1PAR1",
+ "fieldSchemaKey": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "outEvent1",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "outEvent1",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.model.policymodel.events",
+ "source": "Source",
+ "target": "Target",
+ "parameter": {
+ "entry": [
+ {
+ "key": "OE1PAR0",
+ "value": {
+ "key": "OE1PAR0",
+ "fieldSchemaKey": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": "OE1PAR1",
+ "value": {
+ "key": "OE1PAR1",
+ "fieldSchemaKey": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ },
+ "albums": {
+ "key": {
+ "name": "context",
+ "version": "0.0.1"
+ },
+ "albums": {
+ "entry": [
+ {
+ "key": {
+ "name": "contextAlbum0",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "contextAlbum0",
+ "version": "0.0.1"
+ },
+ "scope": "APPLICATION",
+ "isWritable": true,
+ "itemSchema": {
+ "name": "MapType",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "contextAlbum1",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "contextAlbum1",
+ "version": "0.0.1"
+ },
+ "scope": "GLOBAL",
+ "isWritable": false,
+ "itemSchema": {
+ "name": "StringType",
+ "version": "0.0.1"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "schemas": {
+ "key": {
+ "name": "ContextSchemas",
+ "version": "0.0.1"
+ },
+ "schemas": {
+ "entry": [
+ {
+ "key": {
+ "name": "MapType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "MapType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A"
+ }
+ },
+ {
+ "key": {
+ "name": "StringType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "StringType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "org.onap.policy.apex.model.policymodel.concepts.TestContextItem000"
+ }
+ },
+ {
+ "key": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "eventContextItem0",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "java.lang.String"
+ }
+ },
+ {
+ "key": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "eventContextItem1",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "java.lang.Long"
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/model/src/test/resources/models/PolicyModel.junk b/model/src/test/resources/models/PolicyModel.junk
new file mode 100644
index 000000000..613a36ad8
--- /dev/null
+++ b/model/src/test/resources/models/PolicyModel.junk
@@ -0,0 +1,9 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse cursus suscipit faucibus. Pellentesque sagittis, erat placerat ultricies maximus, erat nulla efficitur ex, quis hendrerit tellus urna quis libero. Nullam vitae nisl ut nisl condimentum suscipit. Aenean sagittis condimentum nisi quis condimentum. Suspendisse potenti. Aliquam eget purus a risus viverra volutpat eu eu neque. Phasellus in libero id turpis lobortis malesuada. Praesent dignissim tellus imperdiet faucibus interdum. Donec volutpat, eros non lobortis consectetur, felis arcu consequat purus, a pharetra velit nisi at ante. Etiam ut sem imperdiet justo aliquet tempus at ornare quam.
+
+Integer sed maximus tellus. Nulla venenatis congue massa nec vestibulum. Duis ultrices quis neque ultrices semper. Morbi rhoncus gravida nibh, ut consequat ex. Proin eget ex vel lectus luctus varius. Integer nec consectetur ante. Cras ac aliquam nibh, in fermentum metus. Praesent nec ipsum tristique, ultrices arcu vel, bibendum libero. Curabitur ac odio eget felis blandit accumsan viverra vitae nibh. Integer efficitur eros lectus, et convallis elit consectetur nec. Vivamus tellus sem, vestibulum ut faucibus ut, maximus nec nulla. Donec ex eros, tempus ac justo at, posuere finibus purus. Pellentesque lacinia eu eros nec dignissim. Vestibulum tempus lectus in placerat imperdiet. Sed a diam vitae lorem gravida commodo.
+
+Sed at dolor felis. Ut at luctus libero. Ut faucibus elementum sem. Praesent aliquet tempus magna, eget bibendum nisi ultricies eu. Aenean dictum libero dui, et finibus metus consequat sed. Nullam lobortis diam ut sem imperdiet, nec posuere mauris aliquet. Etiam nec laoreet leo. Vestibulum nec turpis ante. Vivamus imperdiet commodo velit in ultricies. Maecenas facilisis maximus odio vel vestibulum.
+
+Aenean dapibus mi eget eros sodales rhoncus. Mauris dolor mi, feugiat quis egestas id, vestibulum at augue. Vivamus sit amet enim metus. Donec nec ultricies felis. Phasellus aliquam urna lectus, mollis rutrum libero ornare nec. Quisque dictum ante ac dapibus placerat. Ut euismod euismod elit eget commodo. Aenean vestibulum tempus elit quis vestibulum. Integer dapibus ultricies bibendum. Vivamus iaculis egestas magna, a ornare lacus eleifend eu. Fusce non massa ut sapien volutpat molestie vel sit amet sapien. Phasellus hendrerit felis magna, quis pharetra dui finibus sed. Praesent quis accumsan purus, hendrerit viverra felis. Pellentesque semper pretium nisl, in auctor enim interdum ut. Nullam placerat erat vel lacus vestibulum vehicula. Morbi at augue in enim luctus feugiat.
+
+Nunc aliquam auctor turpis id pretium. Donec placerat egestas tortor quis blandit. Curabitur sagittis elit eu varius gravida. Fusce eget diam eu sapien convallis pellentesque. Donec ultrices odio id leo pellentesque, eget tempus erat efficitur. Pellentesque ac ultricies purus, ut condimentum libero. Pellentesque pulvinar urna vel sollicitudin commodo. Sed tincidunt sed nulla sed auctor. \ No newline at end of file
diff --git a/model/src/test/resources/models/RealPolicyModel.json b/model/src/test/resources/models/RealPolicyModel.json
new file mode 100644
index 000000000..f084747f2
--- /dev/null
+++ b/model/src/test/resources/models/RealPolicyModel.json
@@ -0,0 +1,3076 @@
+{
+ "key": {
+ "name": "ONAPvCPEPolicyModel",
+ "version": "0.0.1"
+ },
+ "keyInformation": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_KeyInfo",
+ "version": "0.0.1"
+ },
+ "keyInfoMap": {
+ "entry": [
+ {
+ "key": {
+ "name": "AAILookupTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "AAILookupTask",
+ "version": "0.0.1"
+ },
+ "UUID": "bc77813f-e2fa-33e0-aef0-c5b6a8832698",
+ "description": "Generated description for concept referred to by key \"AAILookupTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "APPCLCMRequestType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "APPCLCMRequestType",
+ "version": "0.0.1"
+ },
+ "UUID": "ab26e475-d09d-36cd-a65c-8a8b556f0fa2",
+ "description": "Generated description for concept referred to by key \"APPCLCMRequestType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "APPCLCMResponseType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "APPCLCMResponseType",
+ "version": "0.0.1"
+ },
+ "UUID": "a60b42bb-c308-30ea-be59-5bc54864508b",
+ "description": "Generated description for concept referred to by key \"APPCLCMResponseType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "APPCRestartVNFRequestEvent",
+ "version": "2.0.0"
+ },
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFRequestEvent",
+ "version": "2.0.0"
+ },
+ "UUID": "0b16f8d9-6ee9-30d7-bcd2-e4ded9fccf9b",
+ "description": "Generated description for concept referred to by key \"APPCRestartVNFRequestEvent:2.0.0\""
+ }
+ },
+ {
+ "key": {
+ "name": "APPCRestartVNFRequestTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFRequestTask",
+ "version": "0.0.1"
+ },
+ "UUID": "719ae90e-ab01-322e-ace3-8c379e7c1fbf",
+ "description": "Generated description for concept referred to by key \"APPCRestartVNFRequestTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "APPCRestartVNFResponseEvent",
+ "version": "2.0.0"
+ },
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFResponseEvent",
+ "version": "2.0.0"
+ },
+ "UUID": "7034c5a9-2ea7-3e9e-9ccf-3610c3bf80d9",
+ "description": "Generated description for concept referred to by key \"APPCRestartVNFResponseEvent:2.0.0\""
+ }
+ },
+ {
+ "key": {
+ "name": "APPCRestartVNFResponseTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFResponseTask",
+ "version": "0.0.1"
+ },
+ "UUID": "fe641fd9-6583-37c5-b317-2a33a3ca5ac7",
+ "description": "Generated description for concept referred to by key \"APPCRestartVNFResponseTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "AbatedTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "AbatedTask",
+ "version": "0.0.1"
+ },
+ "UUID": "0eb3974f-4fdc-3c90-b351-34e7e18ff1ab",
+ "description": "Generated description for concept referred to by key \"AbatedTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2"
+ },
+ "value": {
+ "key": {
+ "name": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2"
+ },
+ "UUID": "63ff5c25-f245-37e9-a580-6ac274ced3a7",
+ "description": "Generated description for concept referred to by key \"ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e:1.0.2\""
+ }
+ },
+ {
+ "key": {
+ "name": "ControlLoopExecutionIDAlbum",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ControlLoopExecutionIDAlbum",
+ "version": "0.0.1"
+ },
+ "UUID": "5b2bc0cf-0807-3ab1-9004-f21806d800f0",
+ "description": "Generated description for concept referred to by key \"ControlLoopExecutionIDAlbum:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ },
+ "UUID": "ed8a82ad-52c2-3d58-8c08-601606894b86",
+ "description": "Generated description for concept referred to by key \"ControlLoopLogEvent:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "UUID": "1b175691-6b5d-31f6-bf2d-4be95a01f92e",
+ "description": "Generated description for concept referred to by key \"ControlLoopLogTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "DeniedTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "DeniedTask",
+ "version": "0.0.1"
+ },
+ "UUID": "00142e3c-ee3b-323f-9490-6e4b7f34b09f",
+ "description": "Generated description for concept referred to by key \"DeniedTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "GetVCPEStateTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GetVCPEStateTask",
+ "version": "0.0.1"
+ },
+ "UUID": "644d2a3d-0f3a-3664-8000-280c400a5cc1",
+ "description": "Generated description for concept referred to by key \"GetVCPEStateTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "GuardDecisionAttributesType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardDecisionAttributesType",
+ "version": "0.0.1"
+ },
+ "UUID": "5f6dff51-c183-322f-9aba-c6074aa0ece5",
+ "description": "Generated description for concept referred to by key \"GuardDecisionAttributesType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "GuardRequestEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardRequestEvent",
+ "version": "0.0.1"
+ },
+ "UUID": "fb383a58-715b-3972-a3e6-38010a8de234",
+ "description": "Generated description for concept referred to by key \"GuardRequestEvent:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "GuardRequestTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardRequestTask",
+ "version": "0.0.1"
+ },
+ "UUID": "0427d63c-da78-334c-a5bd-95fbbb162398",
+ "description": "Generated description for concept referred to by key \"GuardRequestTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "GuardResponseEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardResponseEvent",
+ "version": "0.0.1"
+ },
+ "UUID": "395f6d46-cf24-3d3e-b1fd-1a189a58993d",
+ "description": "Generated description for concept referred to by key \"GuardResponseEvent:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "GuardResponseTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardResponseTask",
+ "version": "0.0.1"
+ },
+ "UUID": "1a8b3f30-a7aa-330b-8131-4aea06ad6934",
+ "description": "Generated description for concept referred to by key \"GuardResponseTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "NoAAILookupTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "NoAAILookupTask",
+ "version": "0.0.1"
+ },
+ "UUID": "648bc8f9-ad2b-3a1b-abe2-89401645f191",
+ "description": "Generated description for concept referred to by key \"NoAAILookupTask:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ONAPvCPEPolicyModel",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel",
+ "version": "0.0.1"
+ },
+ "UUID": "cf1aa7f4-6fe3-3cba-90b4-49dcf46f0d57",
+ "description": "Generated description for concept referred to by key \"ONAPvCPEPolicyModel:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Albums",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Albums",
+ "version": "0.0.1"
+ },
+ "UUID": "13f8471b-2b9c-32e0-940b-fe640ea442cf",
+ "description": "Generated description for concept referred to by key \"ONAPvCPEPolicyModel_Albums:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Events",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Events",
+ "version": "0.0.1"
+ },
+ "UUID": "4b8e6653-731d-38c5-a195-0cadf533a7a1",
+ "description": "Generated description for concept referred to by key \"ONAPvCPEPolicyModel_Events:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_KeyInfo",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_KeyInfo",
+ "version": "0.0.1"
+ },
+ "UUID": "87a9d6da-7d4b-3041-8a70-49442750d590",
+ "description": "Generated description for concept referred to by key \"ONAPvCPEPolicyModel_KeyInfo:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Policies",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Policies",
+ "version": "0.0.1"
+ },
+ "UUID": "6220cca4-66f5-3d1b-9f19-688a9b4b70f5",
+ "description": "Generated description for concept referred to by key \"ONAPvCPEPolicyModel_Policies:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Schemas",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Schemas",
+ "version": "0.0.1"
+ },
+ "UUID": "3df4eef8-e764-3398-afe9-86730e20905a",
+ "description": "Generated description for concept referred to by key \"ONAPvCPEPolicyModel_Schemas:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Tasks",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Tasks",
+ "version": "0.0.1"
+ },
+ "UUID": "1781b875-a3e8-3407-98bd-ba9580cfc543",
+ "description": "Generated description for concept referred to by key \"ONAPvCPEPolicyModel_Tasks:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "ReceiveEventPolicy",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ReceiveEventPolicy",
+ "version": "0.0.1"
+ },
+ "UUID": "568b7345-9de1-36d3-b6a3-9b857e6809a1",
+ "description": "Generated description for concept referred to by key \"ReceiveEventPolicy:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "RequestIDVNFIDAlbum",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "RequestIDVNFIDAlbum",
+ "version": "0.0.1"
+ },
+ "UUID": "5d8e8298-ded6-30a5-9825-48111dc17a58",
+ "description": "Generated description for concept referred to by key \"RequestIDVNFIDAlbum:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "RestartAPPCRequestPolicy",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "RestartAPPCRequestPolicy",
+ "version": "0.0.1"
+ },
+ "UUID": "33d02162-314b-352b-b8b9-2862e8883894",
+ "description": "Generated description for concept referred to by key \"RestartAPPCRequestPolicy:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "RestartAPPCResponsePolicy",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "RestartAPPCResponsePolicy",
+ "version": "0.0.1"
+ },
+ "UUID": "ef4fcbd2-1609-377c-9875-8d27f7a901df",
+ "description": "Generated description for concept referred to by key \"RestartAPPCResponsePolicy:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "SimpleBooleanType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "SimpleBooleanType",
+ "version": "0.0.1"
+ },
+ "UUID": "7218fb2f-59e3-321d-9ae1-bc97b19eb4ae",
+ "description": "Generated description for concept referred to by key \"SimpleBooleanType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "SimpleLongType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "SimpleLongType",
+ "version": "0.0.1"
+ },
+ "UUID": "2dfcd9ec-a6f9-3f9f-958f-9b36cf4ac574",
+ "description": "Generated description for concept referred to by key \"SimpleLongType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "UUID": "8a4957cf-9493-3a76-8c22-a208e23259af",
+ "description": "Generated description for concept referred to by key \"SimpleStringType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "UUID": "6a8cc68e-dfc8-3403-9c6d-071c886b319c",
+ "description": "Generated description for concept referred to by key \"UUIDType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ },
+ "UUID": "47a4403e-3074-3964-83ef-93eefaffd192",
+ "description": "Generated description for concept referred to by key \"VCPEClosedLoopStatusAlbum:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "VCPEClosedLoopStatusType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VCPEClosedLoopStatusType",
+ "version": "0.0.1"
+ },
+ "UUID": "6e7dced1-53f1-39e2-b4e6-412b75d5b9e6",
+ "description": "Generated description for concept referred to by key \"VCPEClosedLoopStatusType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "UUID": "5e56a3fd-f82a-3ced-821b-b9fbaf65d367",
+ "description": "Generated description for concept referred to by key \"VCPEStateUpdatedEvent:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "VirtualControlLoopEventType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VirtualControlLoopEventType",
+ "version": "0.0.1"
+ },
+ "UUID": "15aca887-8f6c-3713-8114-0f49f03adab7",
+ "description": "Generated description for concept referred to by key \"VirtualControlLoopEventType:0.0.1\""
+ }
+ },
+ {
+ "key": {
+ "name": "VirtualControlLoopNotificationType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VirtualControlLoopNotificationType",
+ "version": "0.0.1"
+ },
+ "UUID": "283f5b0d-d8cd-31b0-91fa-89b9de2e1fda",
+ "description": "Generated description for concept referred to by key \"VirtualControlLoopNotificationType:0.0.1\""
+ }
+ }
+ ]
+ }
+ },
+ "policies": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Policies",
+ "version": "0.0.1"
+ },
+ "policyMap": {
+ "entry": [
+ {
+ "key": {
+ "name": "ReceiveEventPolicy",
+ "version": "0.0.1"
+ },
+ "value": {
+ "policyKey": {
+ "name": "ReceiveEventPolicy",
+ "version": "0.0.1"
+ },
+ "template": "Freestyle",
+ "state": {
+ "entry": [
+ {
+ "key": "AbatedState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "AbatedState"
+ },
+ "trigger": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "AbatedOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "AbatedState",
+ "localName": "AbatedOutput"
+ },
+ "outgoingEvent": {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "NULL",
+ "parentKeyVersion": "0.0.0",
+ "parentLocalName": "NULL",
+ "localName": "NULL"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [],
+ "taskSelectionLogic": {
+ "key": "NULL",
+ "logicFlavour": "UNDEFINED",
+ "logic": ""
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "AbatedState",
+ "localName": "ReceiveEventPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "AbatedState",
+ "localName": "AbatedOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key": "GetVCPEState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "GetVCPEState"
+ },
+ "trigger": {
+ "name": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "GetVCPEStateOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "GetVCPEState",
+ "localName": "GetVCPEStateOutput"
+ },
+ "outgoingEvent": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "RequestAAIState"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [],
+ "taskSelectionLogic": {
+ "key": "NULL",
+ "logicFlavour": "UNDEFINED",
+ "logic": ""
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "GetVCPEStateTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "GetVCPEStateTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "GetVCPEState",
+ "localName": "ReceiveEventPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "GetVCPEState",
+ "localName": "GetVCPEStateOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key": "OnsetOrAbatedState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "OnsetOrAbatedState"
+ },
+ "trigger": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "AbatedOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "OnsetOrAbatedState",
+ "localName": "AbatedOutput"
+ },
+ "outgoingEvent": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "AbatedState"
+ }
+ }
+ },
+ {
+ "key": "OnsetOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "OnsetOrAbatedState",
+ "localName": "OnsetOutput"
+ },
+ "outgoingEvent": {
+ "name": "GuardRequestEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "GuardRequestEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "NULL",
+ "parentKeyVersion": "0.0.0",
+ "parentLocalName": "NULL",
+ "localName": "NULL"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskSelectionLogic": {
+ "key": "TaskSelectionLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar returnValue = true;\nvar status = null;\n\nif( executor.inFields.get(\"vnfID\") == null) {\n executor.logger.info(\"OnsetOrAbatedStateTSL: vnfID is null\");\n var vnfName = executor.inFields.get(\"vnfName\");\n var vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfName\"));\n status = vcpeClosedLoopStatus.get(\"closedLoopEventStatus\").toString();\n} else {\n var vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfID\").toString());\n status = vcpeClosedLoopStatus.get(\"closedLoopEventStatus\").toString();\n}\n\nif (status == \"ONSET\") {\n executor.subject.getTaskKey(\"GuardRequestTask\").copyTo(executor.selectedTask);\n} else if (status == \"ABATED\") {\n executor.subject.getTaskKey(\"AbatedTask\").copyTo(executor.selectedTask);\n onsetFlag = executor.isFalse;\n} else {\n executor.message = \"closedLoopEventStatus is \\\"\" + status + \"\\\", it must be either \\\"ONSET\\\" or \\\"ABATED\\\"\";\n returnValue = false;\n}\n\nexecutor.logger.info(\"ReceiveEventPolicyOnsetOrAbatedStateTSL State Selected Task:\" + executor.selectedTask);\n\nreturnValue;"
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "AbatedTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "AbatedTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "OnsetOrAbatedState",
+ "localName": "ReceiveEventPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "OnsetOrAbatedState",
+ "localName": "AbatedOutput"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "GuardRequestTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "OnsetOrAbatedState",
+ "localName": "ReceiveEventPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "OnsetOrAbatedState",
+ "localName": "OnsetOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key": "RequestAAIState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "RequestAAIState"
+ },
+ "trigger": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "RequestAAIStateOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "RequestAAIState",
+ "localName": "RequestAAIStateOutput"
+ },
+ "outgoingEvent": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "OnsetOrAbatedState"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskSelectionLogic": {
+ "key": "NULL",
+ "logicFlavour": "UNDEFINED",
+ "logic": ""
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "AAILookupTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "AAILookupTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "RequestAAIState",
+ "localName": "ReceiveEventPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "ReceiveEventPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "RequestAAIState",
+ "localName": "RequestAAIStateOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "firstState": "GetVCPEState"
+ }
+ },
+ {
+ "key": {
+ "name": "RestartAPPCRequestPolicy",
+ "version": "0.0.1"
+ },
+ "value": {
+ "policyKey": {
+ "name": "RestartAPPCRequestPolicy",
+ "version": "0.0.1"
+ },
+ "template": "Freestyle",
+ "state": {
+ "entry": [
+ {
+ "key": "DeniedState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "DeniedState"
+ },
+ "trigger": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "DeniedOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "DeniedState",
+ "localName": "DeniedOutput"
+ },
+ "outgoingEvent": {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "NULL",
+ "parentKeyVersion": "0.0.0",
+ "parentLocalName": "NULL",
+ "localName": "NULL"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [],
+ "taskSelectionLogic": {
+ "key": "NULL",
+ "logicFlavour": "UNDEFINED",
+ "logic": ""
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "DeniedState",
+ "localName": "RestartAPPCRequestPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "DeniedState",
+ "localName": "DeniedOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key": "PermitOrDenyState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "PermitOrDenyState"
+ },
+ "trigger": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "DenyOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PermitOrDenyState",
+ "localName": "DenyOutput"
+ },
+ "outgoingEvent": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "DeniedState"
+ }
+ }
+ },
+ {
+ "key": "PermitOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PermitOrDenyState",
+ "localName": "PermitOutput"
+ },
+ "outgoingEvent": {
+ "name": "APPCRestartVNFRequestEvent",
+ "version": "2.0.0"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "APPCRestartVNFRequestEvent",
+ "version": "2.0.0"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "NULL",
+ "parentKeyVersion": "0.0.0",
+ "parentLocalName": "NULL",
+ "localName": "NULL"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskSelectionLogic": {
+ "key": "TaskSelectionLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfID\").toString());\n\nvar guardResult = vcpeClosedLoopStatus.get(\"notification\");\n\nif (guardResult == \"OPERATION: GUARD_PERMIT\") {\n executor.subject.getTaskKey(\"APPCRestartVNFRequestTask\").copyTo(executor.selectedTask);\n} else {\n executor.subject.getTaskKey(\"DeniedTask\").copyTo(executor.selectedTask);\n}\n\nexecutor.logger.info(\"RestartAPPCRequestPolicyPermitOrDenyTSL State Selected Task:\" + executor.selectedTask);\n\ntrue;"
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "DeniedTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "APPCRestartVNFRequestTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PermitOrDenyState",
+ "localName": "RestartAPPCRequestPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PermitOrDenyState",
+ "localName": "PermitOutput"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "DeniedTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PermitOrDenyState",
+ "localName": "RestartAPPCRequestPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PermitOrDenyState",
+ "localName": "DenyOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key": "PolicyGuardResponseState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "PolicyGuardResponseState"
+ },
+ "trigger": {
+ "name": "GuardResponseEvent",
+ "version": "0.0.1"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "GuardResponseOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PolicyGuardResponseState",
+ "localName": "GuardResponseOutput"
+ },
+ "outgoingEvent": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "PermitOrDenyState"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [],
+ "taskSelectionLogic": {
+ "key": "NULL",
+ "logicFlavour": "UNDEFINED",
+ "logic": ""
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "GuardResponseTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "GuardResponseTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PolicyGuardResponseState",
+ "localName": "RestartAPPCRequestPolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "RestartAPPCRequestPolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "PolicyGuardResponseState",
+ "localName": "GuardResponseOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "firstState": "PolicyGuardResponseState"
+ }
+ },
+ {
+ "key": {
+ "name": "RestartAPPCResponsePolicy",
+ "version": "0.0.1"
+ },
+ "value": {
+ "policyKey": {
+ "name": "RestartAPPCResponsePolicy",
+ "version": "0.0.1"
+ },
+ "template": "Freestyle",
+ "state": {
+ "entry": [
+ {
+ "key": "ResponseLogState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "ResponseLogState"
+ },
+ "trigger": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "ResponseLogOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "ResponseLogState",
+ "localName": "ResponseLogOutput"
+ },
+ "outgoingEvent": {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "NULL",
+ "parentKeyVersion": "0.0.0",
+ "parentLocalName": "NULL",
+ "localName": "NULL"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [],
+ "taskSelectionLogic": {
+ "key": "NULL",
+ "logicFlavour": "UNDEFINED",
+ "logic": ""
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "ResponseLogState",
+ "localName": "RestartAPPCResponsePolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "ResponseLogState",
+ "localName": "ResponseLogOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "key": "RestartAPPCResponseState",
+ "value": {
+ "stateKey": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "RestartAPPCResponseState"
+ },
+ "trigger": {
+ "name": "APPCRestartVNFResponseEvent",
+ "version": "2.0.0"
+ },
+ "stateOutputs": {
+ "entry": [
+ {
+ "key": "APPCRestartVNFResponseOutput",
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "RestartAPPCResponseState",
+ "localName": "APPCRestartVNFResponseOutput"
+ },
+ "outgoingEvent": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "outgoingEventReference": [
+ {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ }
+ ],
+ "nextState": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "NULL",
+ "localName": "ResponseLogState"
+ }
+ }
+ }
+ ]
+ },
+ "contextAlbumReference": [],
+ "taskSelectionLogic": {
+ "key": "NULL",
+ "logicFlavour": "UNDEFINED",
+ "logic": ""
+ },
+ "stateFinalizerLogicMap": {
+ "entry": []
+ },
+ "defaultTask": {
+ "name": "APPCRestartVNFResponseTask",
+ "version": "0.0.1"
+ },
+ "taskReferences": {
+ "entry": [
+ {
+ "key": {
+ "name": "APPCRestartVNFResponseTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "RestartAPPCResponseState",
+ "localName": "RestartAPPCResponsePolicy"
+ },
+ "outputType": "DIRECT",
+ "output": {
+ "parentKeyName": "RestartAPPCResponsePolicy",
+ "parentKeyVersion": "0.0.1",
+ "parentLocalName": "RestartAPPCResponseState",
+ "localName": "APPCRestartVNFResponseOutput"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "firstState": "RestartAPPCResponseState"
+ }
+ }
+ ]
+ }
+ },
+ "tasks": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Tasks",
+ "version": "0.0.1"
+ },
+ "taskMap": {
+ "entry": [
+ {
+ "key": {
+ "name": "AAILookupTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "AAILookupTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "VCPEStateUpdatedEvent",
+ "value": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfID\").toString());\n\nexecutor.logger.info(\"Executing A&AI Lookup\");\nexecutor.logger.info(vcpeClosedLoopStatus);\n\nvar aaiInfo = vcpeClosedLoopStatus.get(\"AAI\");\nvar returnValue = true;\n\nif (aaiInfo.get(\"vserverName\") == null) {\n executor.message = \"the field vserver.vserver-name must exist in the onset control loop event\";\n executor.logger.warn(executor.message);\n returnValue = false;\n}\nelse if (aaiInfo.get(\"genericVnfVnfId\") == null && aaiInfo.get(\"genericVnfVnfName\") == null) {\n executor.message = \"either the field generic-vnf.vnf-id or generic-vnf.vnf-name must exist\"\n + \" in the onset control loop event\";\n executor.logger.warn(executor.message);\n returnValue = false;\n}\nelse {\n var restManager = new org.onap.policy.rest.RestManager;\n var aaiManager = new org.onap.policy.aai.AaiManager(restManager);\n\n // We need to instantiate the type in order to trigger the static JAXB handling\n // in the AaiCqResponse class\n var aaiCqResponseType = org.onap.policy.aai.AaiCqResponse;\n\n var aaiResponse = aaiManager.getCustomQueryResponse(\n \"http://localhost:54321/OnapVCpeSim/sim\",\n \"aai.username\",\n \"aai.password\",\n executor.inFields.get(\"requestID\"),\n vcpeClosedLoopStatus.get(\"AAI\").get(\"vserverName\")\n );\n\n var genericVnf;\n\n if (aaiInfo.get(\"genericVnfVnfId\") != null) {\n genericVnf = aaiResponse.getGenericVnfByModelInvariantId(aaiInfo.get(\"genericVnfVnfId\"));\n }\n else {\n genericVnf = aaiResponse.getGenericVnfByVnfName(aaiInfo.get(\"genericVnfVnfId\"));\n }\n\n aaiInfo.put(\"genericVnfResourceVersion\", genericVnf.getResourceVersion());\n aaiInfo.put(\"genericVnfVnfName\", genericVnf.getVnfName());\n aaiInfo.put(\"genericVnfProvStatus\", genericVnf.getProvStatus());\n aaiInfo.put(\"genericVnfIsClosedLoopDisabled\", genericVnf.isIsClosedLoopDisabled().toString());\n aaiInfo.put(\"genericVnfVnfType\", genericVnf.getVnfType());\n aaiInfo.put(\"genericVnfInMaint\", genericVnf.isInMaint().toString());\n aaiInfo.put(\"genericVnfServiceId\", genericVnf.getServiceId());\n aaiInfo.put(\"genericVnfVnfId\", genericVnf.getVnfId());\n aaiInfo.put(\"genericVnfOrchestrationStatus\",\n genericVnf.getVfModules().getVfModule().get(0).getOrchestrationStatus());\n\n executor.outFields.put(\"requestID\", executor.inFields.get(\"requestID\"));\n executor.outFields.put(\"vnfID\", executor.inFields.get(\"vnfID\"));\n\n executor.logger.info(executor.outFields);\n}\n\nreturnValue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "APPCRestartVNFRequestTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFRequestTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "APPCRestartVNFRequestEvent",
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFRequestEvent",
+ "version": "2.0.0"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APPC",
+ "parameter": {
+ "entry": [
+ {
+ "key": "APPCLCMRequestEvent",
+ "value": {
+ "key": "APPCLCMRequestEvent",
+ "fieldSchemaKey": {
+ "name": "APPCLCMRequestType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "RequestIDVNFIDAlbum",
+ "version": "0.0.1"
+ },
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar appcRequest = new org.onap.policy.appclcm.AppcLcmDmaapWrapper;\nappcRequest.setBody(new org.onap.policy.appclcm.AppcLcmBody);\nappcRequest.getBody().setInput(new org.onap.policy.appclcm.AppcLcmInput);\nappcRequest.getBody().getInput().setCommonHeader(\n new org.onap.policy.appclcm.AppcLcmCommonHeader);\n\nappcRequest.setVersion(\"2.0.0\");\nappcRequest.setRpcName(\"restart\");\nappcRequest.setCorrelationId(executor.inFields.get(\"requestID\"));\nappcRequest.setType(\"request\");\n\nvar vcpeClosedLoopStatus = executor\n .getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfID\").toString());\n\nappcRequest.getBody().getInput().getCommonHeader().setTimeStamp(java.time.Instant.now());\nappcRequest.getBody().getInput().getCommonHeader().setApiVer(\"2.00\");\nappcRequest.getBody().getInput().getCommonHeader().setOriginatorId(\n executor.inFields.get(\"requestID\").toString());\nappcRequest.getBody().getInput().getCommonHeader().setRequestId(\n executor.inFields.get(\"requestID\"));\nappcRequest.getBody().getInput().getCommonHeader().setSubRequestId(\"1\");\nappcRequest.getBody().getInput().getCommonHeader().getFlags().put(\"ttl\", \"10000\");\nappcRequest.getBody().getInput().getCommonHeader().getFlags().put(\"force\", \"TRUE\");\nappcRequest.getBody().getInput().getCommonHeader().getFlags().put(\"mode\", \"EXCLUSIVE\");\n\nappcRequest.getBody().getInput().setAction(\"Restart\");\nappcRequest.getBody().getInput().setActionIdentifiers(new java.util.HashMap());\nappcRequest.getBody().getInput().getActionIdentifiers().put(\"vnf-id\",\n executor.inFields.get(\"vnfID\").toString());\n\nexecutor.getContextAlbum(\"RequestIDVNFIDAlbum\").put(\n executor.inFields.get(\"requestID\").toString(),\n executor.inFields.get(\"vnfID\"));\n\nvcpeClosedLoopStatus.put(\"notification\", \"OPERATION\");\nvcpeClosedLoopStatus.put(\"notificationTime\", java.lang.System\n .currentTimeMillis());\n\nexecutor.outFields.put(\"APPCLCMRequestEvent\", appcRequest);\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "APPCRestartVNFResponseTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFResponseTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "APPCRestartVNFResponseEvent",
+ "version": "2.0.0"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APPC",
+ "parameter": {
+ "entry": [
+ {
+ "key": "APPCLCMResponseEvent",
+ "value": {
+ "key": "APPCLCMResponseEvent",
+ "fieldSchemaKey": {
+ "name": "APPCLCMResponseType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "VCPEStateUpdatedEvent",
+ "value": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "RequestIDVNFIDAlbum",
+ "version": "0.0.1"
+ },
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * APPC LCM Response code: 100 ACCEPTED\n * 200 ERROR UNEXPECTED ERROR means failure\n * 312 REJECTED DUPLICATE REQUEST\n * 400 SUCCESS\n *\n * Note: Sometimes the corelationId has a -1 at the tail, need to get rid of it when present.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar appcResponse = executor.inFields.get(\"APPCLCMResponseEvent\");\n\nvar requestIDString = appcResponse.getCorrelationId().substr(0, 36);\nexecutor.logger.info(\"requestIDString = \" + requestIDString);\nvar vnfID = executor.getContextAlbum(\"RequestIDVNFIDAlbum\")\n .get(requestIDString);\nexecutor.logger.info(\"Size of RequestIDVNFIDAlbum = \"\n + executor.getContextAlbum(\"RequestIDVNFIDAlbum\").size());\nexecutor.logger.info(\"vnfID = \" + vnfID);\n\nvar returnValue = true;\n\nif (vnfID != null) {\n var vcpeClosedLoopStatus = executor.getContextAlbum(\n \"VCPEClosedLoopStatusAlbum\").get(vnfID.toString());\n var requestId = java.util.UUID.fromString(vcpeClosedLoopStatus\n .get(\"requestID\"));\n\n vcpeClosedLoopStatus.put(\"notificationTime\", java.lang.System\n .currentTimeMillis());\n\n executor.logger.info(\"Got from APPC code: \"\n + org.onap.policy.appclcm.AppcLcmResponseCode\n .toResponseValue(appcResponse.getBody().getOutput()\n .getStatus().getCode()));\n\n if (org.onap.policy.appclcm.AppcLcmResponseCode\n .toResponseValue(appcResponse.getBody().getOutput().getStatus()\n .getCode()) == org.onap.policy.appclcm.AppcLcmResponseCode.SUCCESS) {\n vcpeClosedLoopStatus.put(\"notification\", \"OPERATION_SUCCESS\");\n vcpeClosedLoopStatus.put(\"message\", \"vCPE restarted\");\n executor.getContextAlbum(\"RequestIDVNFIDAlbum\").remove(requestIDString);\n } else if (org.onap.policy.appclcm.AppcLcmResponseCode\n .toResponseValue(appcResponse.getBody().getOutput().getStatus()\n .getCode()) == \"ACCEPTED\"\n || org.onap.policy.appclcm.AppcLcmResponseCode\n .toResponseValue(appcResponse.getBody().getOutput()\n .getStatus().getCode()) == \"REJECT\") {\n executor.logger\n .info(\"Got ACCEPTED 100 or REJECT 312, keep the context, wait for next response. Code is: \"\n + org.onap.policy.appclcm.AppcLcmResponseCode\n .toResponseValue(appcResponse.getBody()\n .getOutput().getStatus().getCode()));\n } else {\n executor.getContextAlbum(\"RequestIDVNFIDAlbum\").remove(requestIDString);\n vcpeClosedLoopStatus.put(\"notification\", \"OPERATION_FAILURE\");\n vcpeClosedLoopStatus.put(\"message\", \"vCPE restart failed\");\n }\n\n executor.outFields.put(\"requestID\", requestId);\n executor.outFields.put(\"vnfID\", vnfID);\n} else {\n executor.message = \"VNF ID not found in context album for request ID \"\n + requestIDString;\n returnValue = false\n}\n\nexecutor.logger.info(executor.outFields);\n\nreturnValue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "AbatedTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "AbatedTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "VCPEStateUpdatedEvent",
+ "value": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar vcpeClosedLoopStatus = null;\nif( executor.inFields.get(\"vnfID\") == null) {\n executor.logger.info(\"AbatedTask: vnfID is null\");\n var vnfName = executor.inFields.get(\"vnfName\");\n vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfName\"));\n} else {\n vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfID\").toString());\n}\n\nvcpeClosedLoopStatus.put(\"notification\", \"FINAL_SUCCESS\");\nvcpeClosedLoopStatus.put(\"notificationTime\", java.lang.System.currentTimeMillis());\nvcpeClosedLoopStatus.put(\"message\", \"situation has been abated\");\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ControlLoopLogTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "ControlLoopLogEvent",
+ "value": {
+ "key": {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "VirtualControlLoopNotification",
+ "value": {
+ "key": "VirtualControlLoopNotification",
+ "fieldSchemaKey": {
+ "name": "VirtualControlLoopNotificationType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar vnfID = executor.inFields.get(\"vnfID\");\nif(vnfID == null) {\n vnfID = executor.inFields.get(\"vnfName\");\n}\nexecutor.logger.info(\"vnfID=\" + vnfID);\n\nvar vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(vnfID.toString());\n\nexecutor.logger.info(\"Logging context information for VNF \\\"\" + vnfID + \"\\\"\");\n\nvar clNotification = new org.onap.policy.controlloop.VirtualControlLoopNotification();\n\nclNotification.setClosedLoopControlName(vcpeClosedLoopStatus.get(\"closedLoopControlName\"));\nclNotification.setClosedLoopAlarmStart(java.time.Instant.ofEpochMilli(vcpeClosedLoopStatus.get(\"closedLoopAlarmStart\")));\nclNotification.setClosedLoopAlarmEnd(java.time.Instant.ofEpochMilli(vcpeClosedLoopStatus.get(\"closedLoopAlarmEnd\")));\nclNotification.setClosedLoopEventClient(vcpeClosedLoopStatus.get(\"closedLoopEventClient\"));\nclNotification.setVersion(vcpeClosedLoopStatus.get(\"version\"));\nclNotification.setRequestId(java.util.UUID.fromString(vcpeClosedLoopStatus.get(\"requestID\")));\nclNotification.setTargetType(vcpeClosedLoopStatus.get(\"target_type\"));\nclNotification.setTarget(vcpeClosedLoopStatus.get(\"target\"));\nclNotification.setFrom(vcpeClosedLoopStatus.get(\"from\"));\nclNotification.setPolicyScope(vcpeClosedLoopStatus.get(\"policyScope\"));\nclNotification.setPolicyName(vcpeClosedLoopStatus.get(\"policyName\"));\nclNotification.setPolicyVersion(vcpeClosedLoopStatus.get(\"policyVersion\"));\nclNotification.setNotification(org.onap.policy.controlloop.ControlLoopNotificationType.toType(vcpeClosedLoopStatus.get(\"notification\")));\nclNotification.setMessage(vcpeClosedLoopStatus.get(\"message\"));\n\nvar notificationInstant = java.time.Instant.ofEpochSecond(vcpeClosedLoopStatus.get(\"notificationTime\"));\nvar notificationTime = java.time.ZonedDateTime.ofInstant(notificationInstant, java.time.ZoneOffset.UTC);\nclNotification.setNotificationTime(notificationTime);\n\nvar aaiInfo = vcpeClosedLoopStatus.get(\"AAI\");\n\nclNotification.getAai().put(\"generic-vnf.resource-version\", aaiInfo.get(\"genericVnfResourceVersion\"));\nclNotification.getAai().put(\"generic-vnf.vnf-name\", aaiInfo.get(\"genericVnfVnfName\"));\nclNotification.getAai().put(\"generic-vnf.prov-status\", aaiInfo.get(\"genericVnfProvStatus\"));\nclNotification.getAai().put(\"generic-vnf.is-closed-loop-disabled\", aaiInfo.get(\"genericVnfIsClosedLoopDisabled\"));\nclNotification.getAai().put(\"generic-vnf.orchestration-status\", aaiInfo.get(\"genericVnfOrchestrationStatus\"));\nclNotification.getAai().put(\"generic-vnf.vnf-type\", aaiInfo.get(\"genericVnfVnfType\"));\nclNotification.getAai().put(\"generic-vnf.in-maint\", aaiInfo.get(\"genericVnfInMaint\"));\nclNotification.getAai().put(\"generic-vnf.service-id\", aaiInfo.get(\"genericVnfServiceId\"));\n\nif(vnfID != null) {\n clNotification.getAai().put(\"generic-vnf.vnf-id\", aaiInfo.get(\"genericVnfVnfId\"));\n}\nexecutor.outFields.put(\"VirtualControlLoopNotification\", clNotification);\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "DeniedTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "DeniedTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "VCPEStateUpdatedEvent",
+ "value": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfID\").toString());\n\nvcpeClosedLoopStatus.put(\"notification\", \"REJECTED\");\nvcpeClosedLoopStatus.put(\"notificationTime\", java.lang.System.currentTimeMillis());\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "GetVCPEStateTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GetVCPEStateTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "DCAE",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "VirtualControlLoopEvent",
+ "value": {
+ "key": "VirtualControlLoopEvent",
+ "fieldSchemaKey": {
+ "name": "VirtualControlLoopEventType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "VCPEStateUpdatedEvent",
+ "value": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "RequestIDVNFIDAlbum",
+ "version": "0.0.1"
+ },
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Note: The incoming closedloop message can be ONSET with both VNF-name and VNF-ID\n * or ABATED with only VNF-name. So need to handle differently. For ABATED case,\n * since we still keep the RequireIDVNFID context album, we can get it from there.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar clEventType = org.onap.policy.controlloop.VirtualControlLoopEvent;\nvar longType = java.lang.Long;\nvar uuidType = java.util.UUID;\n\nvar clEvent = executor.inFields.get(\"VirtualControlLoopEvent\");\n\nexecutor.logger.info(clEvent.toString());\nexecutor.logger.info(clEvent.getClosedLoopControlName());\n\nvar requestID = clEvent.getRequestId();\nexecutor.logger.info(\"requestID = \" + requestID);\nvar vnfID = null;\nvar vcpeClosedLoopStatus = null;\n\nif (clEvent.getAai().get(\"generic-vnf.vnf-id\") != null) {\n vnfID = uuidType.fromString(clEvent.getAai().get(\"generic-vnf.vnf-id\"));\n executor.logger.info(\"vnfID = \" + vnfID);\n vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(vnfID);\n\n if (vcpeClosedLoopStatus == null) {\n executor.logger.info(\"Creating context information for new vCPE VNF \\\"\" + vnfID.toString() + \"\\\"\");\n\n vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").getSchemaHelper().createNewInstance();\n\n vcpeClosedLoopStatus.put(\"closedLoopControlName\", clEvent.getClosedLoopControlName());\n vcpeClosedLoopStatus.put(\"closedLoopAlarmStart\", clEvent.getClosedLoopAlarmStart().toEpochMilli());\n vcpeClosedLoopStatus.put(\"closedLoopEventClient\", clEvent.getClosedLoopEventClient());\n vcpeClosedLoopStatus.put(\"closedLoopEventStatus\", clEvent.getClosedLoopEventStatus().toString());\n vcpeClosedLoopStatus.put(\"version\", clEvent.getVersion());\n vcpeClosedLoopStatus.put(\"requestID\", clEvent.getRequestId().toString());\n vcpeClosedLoopStatus.put(\"target_type\", clEvent.getTargetType().toString());\n vcpeClosedLoopStatus.put(\"target\", clEvent.getTarget());\n vcpeClosedLoopStatus.put(\"from\", clEvent.getFrom());\n vcpeClosedLoopStatus.put(\"policyScope\", \"vCPE\");\n vcpeClosedLoopStatus.put(\"policyName\", \"ONAPvCPEPolicyModel\");\n vcpeClosedLoopStatus.put(\"policyVersion\", \"0.0.1\");\n vcpeClosedLoopStatus.put(\"notification\", \"ACTIVE\");\n vcpeClosedLoopStatus.put(\"notificationTime\", java.lang.System.currentTimeMillis());\n vcpeClosedLoopStatus.put(\"message\", \"\");\n\n var aaiInfo = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").getSchemaHelper().createNewSubInstance(\"VCPE_AAI_Type\");\n\n aaiInfo.put(\"genericVnfResourceVersion\", clEvent.getAai().get(\"generic-vnf.resource-version\"));\n aaiInfo.put(\"genericVnfVnfName\", clEvent.getAai().get(\"generic-vnf.vnf-name\"));\n aaiInfo.put(\"genericVnfProvStatus\", clEvent.getAai().get(\"generic-vnf.prov-status\"));\n aaiInfo.put(\"genericVnfIsClosedLoopDisabled\", clEvent.getAai().get(\"generic-vnf.is-closed-loop-disabled\"));\n aaiInfo.put(\"genericVnfOrchestrationStatus\", clEvent.getAai().get(\"generic-vnf.orchestration-status\"));\n aaiInfo.put(\"genericVnfVnfType\", clEvent.getAai().get(\"generic-vnf.vnf-type\"));\n aaiInfo.put(\"genericVnfInMaint\", clEvent.getAai().get(\"generic-vnf.in-maint\"));\n aaiInfo.put(\"genericVnfServiceId\", clEvent.getAai().get(\"generic-vnf.service-id\"));\n aaiInfo.put(\"genericVnfVnfId\", clEvent.getAai().get(\"generic-vnf.vnf-id\"));\n aaiInfo.put(\"vserverIsClosedLoopDisabled\", clEvent.getAai().get(\"vserver.is-closed-loop-disabled\"));\n aaiInfo.put(\"vserverProvStatus\", clEvent.getAai().get(\"vserver.prov-status\"));\n aaiInfo.put(\"vserverName\", clEvent.getAai().get(\"vserver.vserver-name\"));\n\n vcpeClosedLoopStatus.put(\"AAI\", aaiInfo);\n\n if (clEvent.getClosedLoopAlarmEnd() != null) {\n vcpeClosedLoopStatus.put(\"closedLoopAlarmEnd\", clEvent.getClosedLoopAlarmEnd().toEpochMilli());\n } else {\n vcpeClosedLoopStatus.put(\"closedLoopAlarmEnd\", java.lang.Long.valueOf(0));\n }\n\n executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").put(vnfID.toString(), vcpeClosedLoopStatus);\n\n executor.logger.info(\"Created context information for new vCPE VNF \\\"\" + vnfID.toString() + \"\\\"\");\n }\n\n executor.outFields.put(\"requestID\", requestID);\n executor.outFields.put(\"vnfID\", vnfID);\n\n executor.logger.info(executor.outFields);\n}\nelse {\n executor.logger.info(\"No vnf-id in VirtualControlLoopEvent, status:\" + clEvent.getClosedLoopEventStatus().toString());\n var vnfName = clEvent.getAai().get(\"generic-vnf.vnf-name\");\n executor.logger.info(\"No vnf-id in VirtualControlLoopEvent for \" + vnfName);\n\n vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(vnfName.toString());\n\n if (vcpeClosedLoopStatus == null) {\n executor.logger.info(\"Creating context information for new vCPE VNF \\\"\" + vnfName.toString() + \"\\\"\");\n\n vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").getSchemaHelper().createNewInstance();\n\n vcpeClosedLoopStatus.put(\"closedLoopControlName\", clEvent.getClosedLoopControlName());\n vcpeClosedLoopStatus.put(\"closedLoopAlarmStart\", clEvent.getClosedLoopAlarmStart().toEpochMilli());\n vcpeClosedLoopStatus.put(\"closedLoopEventClient\", clEvent.getClosedLoopEventClient());\n vcpeClosedLoopStatus.put(\"closedLoopEventStatus\", clEvent.getClosedLoopEventStatus().toString());\n vcpeClosedLoopStatus.put(\"version\", clEvent.getVersion());\n vcpeClosedLoopStatus.put(\"requestID\", clEvent.getRequestId().toString());\n vcpeClosedLoopStatus.put(\"target_type\", clEvent.getTargetType().toString());\n vcpeClosedLoopStatus.put(\"target\", clEvent.getTarget());\n vcpeClosedLoopStatus.put(\"from\", clEvent.getFrom());\n vcpeClosedLoopStatus.put(\"policyScope\", \"vCPE\");\n vcpeClosedLoopStatus.put(\"policyName\", \"ONAPvCPEPolicyModel\");\n vcpeClosedLoopStatus.put(\"policyVersion\", \"0.0.1\");\n vcpeClosedLoopStatus.put(\"notification\", \"ACTIVE\");\n vcpeClosedLoopStatus.put(\"notificationTime\", java.lang.System.currentTimeMillis());\n vcpeClosedLoopStatus.put(\"message\", \"\");\n\n var aaiInfo = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").getSchemaHelper().createNewSubInstance(\"VCPE_AAI_Type\");\n\n aaiInfo.put(\"genericVnfVnfName\", clEvent.getAai().get(\"generic-vnf.vnf-name\"));\n vcpeClosedLoopStatus.put(\"AAI\", aaiInfo);\n\n if (clEvent.getClosedLoopAlarmEnd() != null) {\n vcpeClosedLoopStatus.put(\"closedLoopAlarmEnd\", clEvent.getClosedLoopAlarmEnd().toEpochMilli());\n } else {\n vcpeClosedLoopStatus.put(\"closedLoopAlarmEnd\", java.lang.Long.valueOf(0));\n }\n\n executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").put(vnfName.toString(), vcpeClosedLoopStatus);\n\n executor.logger.info(\"Created context information for new vCPE VNF \\\"\" + vnfName.toString() + \"\\\"\");\n }\n executor.outFields.put(\"requestID\", requestID);\n executor.outFields.put(\"vnfName\", vnfName);\n executor.logger.info(executor.outFields);\n}\n\ntrue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "GuardRequestTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardRequestTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "GuardRequestEvent",
+ "value": {
+ "key": {
+ "name": "GuardRequestEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "decisionAttributes",
+ "value": {
+ "key": "decisionAttributes",
+ "fieldSchemaKey": {
+ "name": "GuardDecisionAttributesType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "onapName",
+ "value": {
+ "key": "onapName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "ControlLoopExecutionIDAlbum",
+ "version": "0.0.1"
+ },
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(\n executor.inFields.get(\"vnfID\").toString());\n\nvar guardDecisionAttributes = executor.subject.getOutFieldSchemaHelper(\"decisionAttributes\").createNewInstance();\n\nguardDecisionAttributes.put(\"actor\", \"APPC\");\nguardDecisionAttributes.put(\"recipe\", \"Restart\");\nguardDecisionAttributes.put(\"target\", executor.inFields.get(\"vnfID\").toString());\nguardDecisionAttributes.put(\"clname\", \"APEXvCPEImplementation\");\n\nexecutor.logger.info(guardDecisionAttributes);\n\nexecutor.outFields.put(\"decisionAttributes\", guardDecisionAttributes);\nexecutor.outFields.put(\"onapName\", \"PDPD\");\n\nexecutor.getContextAlbum(\"ControlLoopExecutionIDAlbum\").put(executor.executionId.toString(),\n executor.inFields.get(\"vnfID\"));\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "GuardResponseTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardResponseTask",
+ "version": "0.0.1"
+ },
+ "inputEvent": {
+ "key": {
+ "name": "GuardResponseEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "decision",
+ "value": {
+ "key": "decision",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "details",
+ "value": {
+ "key": "details",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ },
+ "outputEvents": {
+ "entry": [
+ {
+ "key": "VCPEStateUpdatedEvent",
+ "value": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [
+ {
+ "name": "ControlLoopExecutionIDAlbum",
+ "version": "0.0.1"
+ },
+ {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ }
+ ],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar vnfID = executor.getContextAlbum(\"ControlLoopExecutionIDAlbum\").remove(executor.executionId.toString());\n\nexecutor.logger.info(\"Continuing execution with VNF ID: \" + vnfID);\n\nvar vcpeClosedLoopStatus = executor.getContextAlbum(\"VCPEClosedLoopStatusAlbum\").get(vnfID.toString());\nexecutor.logger.info(vcpeClosedLoopStatus);\n\nvar guardResult = executor.inFields.get(\"decision\");\nvar returnValue = true;\n\nif (guardResult == \"PERMIT\") {\n vcpeClosedLoopStatus.put(\"notification\", \"OPERATION: GUARD_PERMIT\");\n} else if (guardResult == \"DENY\") {\n vcpeClosedLoopStatus.put(\"notification\", \"OPERATION: GUARD_DENY\");\n} else {\n executor.message = \"guard result must be either \\\"PERMIT\\\" or \\\"DENY\\\"\";\n returnValue = false;\n}\n\nvar uuidType = java.util.UUID;\nvar requestID = uuidType.fromString(vcpeClosedLoopStatus.get(\"requestID\"));\n\nexecutor.outFields.put(\"requestID\", requestID);\nexecutor.outFields.put(\"vnfID\", vnfID);\n\nexecutor.logger.info(executor.outFields);\n\n\nreturnValue;"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "NoAAILookupTask",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "NoAAILookupTask",
+ "version": "0.0.1"
+ },
+ "taskParameters": {
+ "entry": []
+ },
+ "contextAlbumReference": [],
+ "taskLogic": {
+ "key": "TaskLogic",
+ "logicFlavour": "JAVASCRIPT",
+ "logic": "/*\n * ============LICENSE_START=======================================================\n * Copyright (C) 2016-2018 Ericsson. All rights reserved.\n * Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "events": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Events",
+ "version": "0.0.1"
+ },
+ "eventMap": {
+ "entry": [
+ {
+ "key": {
+ "name": "APPCRestartVNFRequestEvent",
+ "version": "2.0.0"
+ },
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFRequestEvent",
+ "version": "2.0.0"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APPC",
+ "parameter": {
+ "entry": [
+ {
+ "key": "APPCLCMRequestEvent",
+ "value": {
+ "key": "APPCLCMRequestEvent",
+ "fieldSchemaKey": {
+ "name": "APPCLCMRequestType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ },
+ {
+ "key": {
+ "name": "APPCRestartVNFResponseEvent",
+ "version": "2.0.0"
+ },
+ "value": {
+ "key": {
+ "name": "APPCRestartVNFResponseEvent",
+ "version": "2.0.0"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APPC",
+ "parameter": {
+ "entry": [
+ {
+ "key": "APPCLCMResponseEvent",
+ "value": {
+ "key": "APPCLCMResponseEvent",
+ "fieldSchemaKey": {
+ "name": "APPCLCMResponseType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ },
+ {
+ "key": {
+ "name": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2"
+ },
+ "value": {
+ "key": {
+ "name": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "DCAE",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "VirtualControlLoopEvent",
+ "value": {
+ "key": "VirtualControlLoopEvent",
+ "fieldSchemaKey": {
+ "name": "VirtualControlLoopEventType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ },
+ {
+ "key": {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ControlLoopLogEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "VirtualControlLoopNotification",
+ "value": {
+ "key": "VirtualControlLoopNotification",
+ "fieldSchemaKey": {
+ "name": "VirtualControlLoopNotificationType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ },
+ {
+ "key": {
+ "name": "GuardRequestEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardRequestEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "decisionAttributes",
+ "value": {
+ "key": "decisionAttributes",
+ "fieldSchemaKey": {
+ "name": "GuardDecisionAttributesType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "onapName",
+ "value": {
+ "key": "onapName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ },
+ {
+ "key": {
+ "name": "GuardResponseEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardResponseEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "decision",
+ "value": {
+ "key": "decision",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "details",
+ "value": {
+ "key": "details",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ },
+ {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VCPEStateUpdatedEvent",
+ "version": "0.0.1"
+ },
+ "nameSpace": "org.onap.policy.apex.onap.vcpe",
+ "source": "APEX",
+ "target": "APEX",
+ "parameter": {
+ "entry": [
+ {
+ "key": "requestID",
+ "value": {
+ "key": "requestID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfID",
+ "value": {
+ "key": "vnfID",
+ "fieldSchemaKey": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "optional": false
+ }
+ },
+ {
+ "key": "vnfName",
+ "value": {
+ "key": "vnfName",
+ "fieldSchemaKey": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "optional": true
+ }
+ }
+ ]
+ },
+ "toscaPolicyState": ""
+ }
+ }
+ ]
+ }
+ },
+ "albums": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Albums",
+ "version": "0.0.1"
+ },
+ "albums": {
+ "entry": [
+ {
+ "key": {
+ "name": "ControlLoopExecutionIDAlbum",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "ControlLoopExecutionIDAlbum",
+ "version": "0.0.1"
+ },
+ "scope": "policy",
+ "isWritable": true,
+ "itemSchema": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "RequestIDVNFIDAlbum",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "RequestIDVNFIDAlbum",
+ "version": "0.0.1"
+ },
+ "scope": "policy",
+ "isWritable": true,
+ "itemSchema": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ }
+ }
+ },
+ {
+ "key": {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VCPEClosedLoopStatusAlbum",
+ "version": "0.0.1"
+ },
+ "scope": "policy",
+ "isWritable": true,
+ "itemSchema": {
+ "name": "VCPEClosedLoopStatusType",
+ "version": "0.0.1"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "schemas": {
+ "key": {
+ "name": "ONAPvCPEPolicyModel_Schemas",
+ "version": "0.0.1"
+ },
+ "schemas": {
+ "entry": [
+ {
+ "key": {
+ "name": "APPCLCMRequestType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "APPCLCMRequestType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "org.onap.policy.appclcm.AppcLcmDmaapWrapper"
+ }
+ },
+ {
+ "key": {
+ "name": "APPCLCMResponseType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "APPCLCMResponseType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "org.onap.policy.appclcm.AppcLcmDmaapWrapper"
+ }
+ },
+ {
+ "key": {
+ "name": "GuardDecisionAttributesType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "GuardDecisionAttributesType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Avro",
+ "schemaDefinition": "{\n \"type\": \"record\",\n \"name\": \"GuardDecisionAttributes_Type\",\n \"namespace\": \"org.onap.policy.apex.onap.vcpe\",\n \"fields\": [\n {\n \"name\": \"actor\",\n \"type\": \"string\"\n },\n {\n \"name\": \"recipe\",\n \"type\": \"string\"\n },\n {\n \"name\": \"target\",\n \"type\": \"string\"\n },\n {\n \"name\": \"clname\",\n \"type\": \"string\"\n }\n ]\n}"
+ }
+ },
+ {
+ "key": {
+ "name": "SimpleBooleanType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "SimpleBooleanType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "java.lang.Boolean"
+ }
+ },
+ {
+ "key": {
+ "name": "SimpleLongType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "SimpleLongType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "java.lang.Long"
+ }
+ },
+ {
+ "key": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "SimpleStringType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "java.lang.String"
+ }
+ },
+ {
+ "key": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "UUIDType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "java.util.UUID"
+ }
+ },
+ {
+ "key": {
+ "name": "VCPEClosedLoopStatusType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VCPEClosedLoopStatusType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Avro",
+ "schemaDefinition": "{\n \"type\": \"record\",\n \"name\": \"VCPEClosedLoopStatus\",\n \"fields\": [\n {\n \"name\": \"AAI\",\n \"type\": {\n \"type\": \"record\",\n \"name\": \"VCPE_AAI_Type\",\n \"namespace\": \"org.onap.policy.apex.onap.vcpe\",\n \"fields\": [\n {\n \"name\": \"genericVnfResourceVersion\",\n \"type\": \"string\"\n },\n {\n \"name\": \"genericVnfVnfName\",\n \"type\": \"string\"\n },\n {\n \"name\": \"genericVnfProvStatus\",\n \"type\": \"string\"\n },\n {\n \"name\": \"genericVnfIsClosedLoopDisabled\",\n \"type\": \"string\"\n },\n {\n \"name\": \"genericVnfOrchestrationStatus\",\n \"type\": \"string\"\n },\n {\n \"name\": \"genericVnfVnfType\",\n \"type\": \"string\"\n },\n {\n \"name\": \"genericVnfInMaint\",\n \"type\": \"string\"\n },\n {\n \"name\": \"genericVnfServiceId\",\n \"type\": \"string\"\n },\n {\n \"name\": \"genericVnfVnfId\",\n \"type\": \"string\"\n },\n {\n \"name\": \"vserverIsClosedLoopDisabled\",\n \"type\": \"string\"\n },\n {\n \"name\": \"vserverName\",\n \"type\": \"string\"\n },\n {\n \"name\": \"vserverProvStatus\",\n \"type\": \"string\"\n }\n ]\n }\n },\n {\n \"name\": \"closedLoopAlarmStart\",\n \"type\": \"long\"\n },\n {\n \"name\": \"closedLoopAlarmEnd\",\n \"type\": \"long\"\n },\n {\n \"name\": \"closedLoopControlName\",\n \"type\": \"string\"\n },\n {\n \"name\": \"version\",\n \"type\": \"string\"\n },\n {\n \"name\": \"requestID\",\n \"type\": \"string\"\n },\n {\n \"name\": \"closedLoopEventClient\",\n \"type\": \"string\"\n },\n {\n \"name\": \"closedLoopEventStatus\",\n \"type\": \"string\"\n },\n {\n \"name\": \"target_type\",\n \"type\": \"string\"\n },\n {\n \"name\": \"target\",\n \"type\": \"string\"\n },\n {\n \"name\": \"from\",\n \"type\": \"string\"\n },\n {\n \"name\": \"policyScope\",\n \"type\": \"string\"\n },\n {\n \"name\": \"policyName\",\n \"type\": \"string\"\n },\n {\n \"name\": \"policyVersion\",\n \"type\": \"string\"\n },\n {\n \"name\": \"notification\",\n \"type\": \"string\"\n },\n {\n \"name\": \"notificationTime\",\n \"type\": \"long\"\n },\n {\n \"name\": \"message\",\n \"type\": \"string\"\n }\n ]\n}"
+ }
+ },
+ {
+ "key": {
+ "name": "VirtualControlLoopEventType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VirtualControlLoopEventType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "org.onap.policy.controlloop.VirtualControlLoopEvent"
+ }
+ },
+ {
+ "key": {
+ "name": "VirtualControlLoopNotificationType",
+ "version": "0.0.1"
+ },
+ "value": {
+ "key": {
+ "name": "VirtualControlLoopNotificationType",
+ "version": "0.0.1"
+ },
+ "schemaFlavour": "Java",
+ "schemaDefinition": "org.onap.policy.controlloop.VirtualControlLoopNotification"
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/model/src/test/resources/path/to/apex/logic/funkylogic/LogicParentLogicParentLocalNameLogicInstanceName.funkylogic b/model/src/test/resources/path/to/apex/logic/funkylogic/LogicParentLogicParentLocalNameLogicInstanceName.funkylogic
new file mode 100644
index 000000000..7ccf3da88
--- /dev/null
+++ b/model/src/test/resources/path/to/apex/logic/funkylogic/LogicParentLogicParentLocalNameLogicInstanceName.funkylogic
@@ -0,0 +1,21 @@
+#-------------------------------------------------------------------------------
+# ============LICENSE_START=======================================================
+# Copyright (C) 2016-2018 Ericsson. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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=========================================================
+#-------------------------------------------------------------------------------
+
+Way out man, this is funky logic! \ No newline at end of file
diff --git a/model/src/test/resources/testdir/testfile.xml b/model/src/test/resources/testdir/testfile.xml
new file mode 100644
index 000000000..ddffc5822
--- /dev/null
+++ b/model/src/test/resources/testdir/testfile.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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=========================================================
+-->