diff options
7 files changed, 187 insertions, 17 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java index 83c51eadb..18a62ae94 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationComposition.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. + * Copyright (C) 2021-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,12 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut @NonNull private AutomationCompositionOrderedState orderedState = AutomationCompositionOrderedState.UNINITIALISED; + @NonNull + private DeployState deployState = DeployState.UNDEPLOYED; + + @NonNull + private LockState lockState = LockState.LOCKED; + private Map<UUID, AutomationCompositionElement> elements; @NonNull @@ -65,6 +71,8 @@ public class AutomationComposition extends ToscaEntity implements Comparable<Aut this.compositionId = otherAutomationComposition.compositionId; this.state = otherAutomationComposition.state; this.orderedState = otherAutomationComposition.orderedState; + this.deployState = otherAutomationComposition.deployState; + this.lockState = otherAutomationComposition.lockState; this.elements = PfUtils.mapMap(otherAutomationComposition.elements, AutomationCompositionElement::new); this.primed = otherAutomationComposition.primed; } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java index b153ef508..ab234f604 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionElement.java @@ -53,6 +53,12 @@ public class AutomationCompositionElement { private AutomationCompositionState state = AutomationCompositionState.UNINITIALISED; @NonNull + private DeployState deployState = DeployState.UNDEPLOYED; + + @NonNull + private LockState lockState = LockState.LOCKED; + + @NonNull private AutomationCompositionOrderedState orderedState = AutomationCompositionOrderedState.UNINITIALISED; private ToscaServiceTemplate toscaServiceTemplateFragment; @@ -77,5 +83,7 @@ public class AutomationCompositionElement { this.toscaServiceTemplateFragment = otherElement.toscaServiceTemplateFragment; this.description = otherElement.description; this.properties = PfUtils.mapMap(otherElement.properties, UnaryOperator.identity()); + this.deployState = otherElement.deployState; + this.lockState = otherElement.lockState; } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java index f9cc880d0..00f83122d 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. + * Copyright (C) 2021-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,8 @@ import org.apache.commons.lang3.ObjectUtils; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.DeployState; +import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.common.parameters.annotations.NotNull; import org.onap.policy.common.parameters.annotations.Valid; import org.onap.policy.models.base.PfAuthorative; @@ -88,6 +90,14 @@ public class JpaAutomationComposition extends Validated private AutomationCompositionOrderedState orderedState; @Column + @NotNull + private DeployState deployState; + + @Column + @NotNull + private LockState lockState; + + @Column private String description; @Column(columnDefinition = "TINYINT DEFAULT 1") @@ -103,7 +113,7 @@ public class JpaAutomationComposition extends Validated */ public JpaAutomationComposition() { this(UUID.randomUUID().toString(), new PfConceptKey(), UUID.randomUUID().toString(), - AutomationCompositionState.UNINITIALISED, new ArrayList<>()); + AutomationCompositionState.UNINITIALISED, new ArrayList<>(), DeployState.UNDEPLOYED, LockState.LOCKED); } /** @@ -117,12 +127,15 @@ public class JpaAutomationComposition extends Validated */ public JpaAutomationComposition(@NonNull final String instanceId, @NonNull final PfConceptKey key, @NonNull final String compositionId, @NonNull final AutomationCompositionState state, - @NonNull final List<JpaAutomationCompositionElement> elements) { + @NonNull final List<JpaAutomationCompositionElement> elements, + @NonNull final DeployState deployState, @NonNull final LockState lockState) { this.instanceId = instanceId; this.name = key.getName(); this.version = key.getVersion(); this.compositionId = compositionId; this.state = state; + this.deployState = deployState; + this.lockState = lockState; this.elements = elements; } @@ -138,6 +151,8 @@ public class JpaAutomationComposition extends Validated this.compositionId = copyConcept.compositionId; this.state = copyConcept.state; this.orderedState = copyConcept.orderedState; + this.deployState = copyConcept.deployState; + this.lockState = copyConcept.lockState; this.description = copyConcept.description; this.elements = PfUtils.mapList(copyConcept.elements, JpaAutomationCompositionElement::new); this.primed = copyConcept.primed; @@ -162,6 +177,8 @@ public class JpaAutomationComposition extends Validated automationComposition.setCompositionId(UUID.fromString(compositionId)); automationComposition.setState(state); automationComposition.setOrderedState(orderedState != null ? orderedState : state.asOrderedState()); + automationComposition.setDeployState(deployState); + automationComposition.setLockState(lockState); automationComposition.setDescription(description); automationComposition.setPrimed(primed); automationComposition.setElements(new LinkedHashMap<>(this.elements.size())); @@ -180,6 +197,8 @@ public class JpaAutomationComposition extends Validated this.compositionId = automationComposition.getCompositionId().toString(); this.state = automationComposition.getState(); this.orderedState = automationComposition.getOrderedState(); + this.deployState = automationComposition.getDeployState(); + this.lockState = automationComposition.getLockState(); this.description = automationComposition.getDescription(); this.primed = automationComposition.getPrimed(); @@ -231,6 +250,16 @@ public class JpaAutomationComposition extends Validated return result; } + result = ObjectUtils.compare(deployState, other.deployState); + if (result != 0) { + return result; + } + + result = ObjectUtils.compare(lockState, other.lockState); + if (result != 0) { + return result; + } + result = ObjectUtils.compare(description, other.description); if (result != 0) { return result; diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java index 743bb7fd3..4020243bb 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElement.java @@ -42,6 +42,8 @@ import org.apache.commons.lang3.ObjectUtils; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.DeployState; +import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.common.parameters.annotations.NotNull; import org.onap.policy.common.parameters.annotations.Valid; import org.onap.policy.models.base.PfAuthorative; @@ -91,6 +93,14 @@ public class JpaAutomationCompositionElement extends Validated private AutomationCompositionOrderedState orderedState; @Column + @NotNull + private DeployState deployState; + + @Column + @NotNull + private LockState lockState; + + @Column private String description; @Lob @@ -113,7 +123,8 @@ public class JpaAutomationCompositionElement extends Validated * @param instanceId The id of the automation composition instance */ public JpaAutomationCompositionElement(@NonNull final String elementId, @NonNull final String instanceId) { - this(elementId, instanceId, new PfConceptKey(), AutomationCompositionState.UNINITIALISED); + this(elementId, instanceId, new PfConceptKey(), + AutomationCompositionState.UNINITIALISED, DeployState.UNDEPLOYED, LockState.LOCKED); } /** @@ -126,11 +137,14 @@ public class JpaAutomationCompositionElement extends Validated */ public JpaAutomationCompositionElement(@NonNull final String elementId, @NonNull final String instanceId, @NonNull final PfConceptKey definition, - @NonNull final AutomationCompositionState state) { + @NonNull final AutomationCompositionState state, + @NonNull final DeployState deployState, @NonNull final LockState lockState) { this.elementId = elementId; this.instanceId = instanceId; this.definition = definition; this.state = state; + this.deployState = deployState; + this.lockState = lockState; } /** @@ -147,6 +161,8 @@ public class JpaAutomationCompositionElement extends Validated this.orderedState = copyConcept.orderedState; this.description = copyConcept.description; this.properties = (copyConcept.properties != null ? new LinkedHashMap<>(copyConcept.properties) : null); + this.deployState = copyConcept.deployState; + this.lockState = copyConcept.lockState; } /** @@ -169,6 +185,8 @@ public class JpaAutomationCompositionElement extends Validated element.setOrderedState(orderedState != null ? orderedState : state.asOrderedState()); element.setDescription(description); element.setProperties(PfUtils.mapMap(properties, UnaryOperator.identity())); + element.setDeployState(deployState); + element.setLockState(lockState); return element; } @@ -181,6 +199,8 @@ public class JpaAutomationCompositionElement extends Validated this.orderedState = element.getOrderedState(); this.description = element.getDescription(); properties = PfUtils.mapMap(element.getProperties(), UnaryOperator.identity()); + this.deployState = element.getDeployState(); + this.lockState = element.getLockState(); } @Override @@ -222,6 +242,16 @@ public class JpaAutomationCompositionElement extends Validated return result; } + result = ObjectUtils.compare(deployState, other.deployState); + if (result != 0) { + return result; + } + + result = ObjectUtils.compare(lockState, other.lockState); + if (result != 0) { + return result; + } + return ObjectUtils.compare(description, other.description); } } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java index 83e13c74a..3274833ca 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionElementTest.java @@ -35,6 +35,8 @@ import org.junit.jupiter.api.Test; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; +import org.onap.policy.clamp.models.acm.concepts.DeployState; +import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.clamp.models.acm.concepts.Participant; import org.onap.policy.clamp.models.acm.utils.CommonTestData; import org.onap.policy.common.utils.coder.CoderException; @@ -56,6 +58,10 @@ class JpaAutomationCompositionElementTest { @Test void testJpaAutomationCompositionElementConstructor() { assertThatThrownBy(() -> { + new JpaAutomationCompositionElement((AutomationCompositionElement) null); + }).hasMessageMatching("authorativeConcept is marked .*ull but is null"); + + assertThatThrownBy(() -> { new JpaAutomationCompositionElement((JpaAutomationCompositionElement) null); }).hasMessageMatching("copyConcept is marked .*ull but is null"); @@ -72,21 +78,38 @@ class JpaAutomationCompositionElementTest { }).hasMessageMatching(NULL_ELEMENT_ID_ERROR); assertThatThrownBy(() -> { - new JpaAutomationCompositionElement(null, null, null, null); + new JpaAutomationCompositionElement(null, null, null, null, null, null); }).hasMessageMatching(NULL_ELEMENT_ID_ERROR); assertThatThrownBy(() -> { - new JpaAutomationCompositionElement("key", null, null, AutomationCompositionState.UNINITIALISED); + new JpaAutomationCompositionElement("key", null, null, + AutomationCompositionState.UNINITIALISED, DeployState.UNDEPLOYED, LockState.LOCKED); }).hasMessageMatching(NULL_INSTANCE_ID_ERROR); assertThatThrownBy(() -> { - new JpaAutomationCompositionElement("key", "key", new PfConceptKey(), null); + new JpaAutomationCompositionElement("key", "key", null, + AutomationCompositionState.UNINITIALISED, DeployState.UNDEPLOYED, LockState.LOCKED); + }).hasMessageMatching("definition" + NULL_ERROR); + + assertThatThrownBy(() -> { + new JpaAutomationCompositionElement("key", "key", new PfConceptKey(), null, + DeployState.UNDEPLOYED, LockState.LOCKED); }).hasMessageMatching("state" + NULL_ERROR); + assertThatThrownBy(() -> { + new JpaAutomationCompositionElement("key", "key", new PfConceptKey(), + AutomationCompositionState.UNINITIALISED, null, LockState.LOCKED); + }).hasMessageMatching("deployState" + NULL_ERROR); + + assertThatThrownBy(() -> { + new JpaAutomationCompositionElement("key", "key", new PfConceptKey(), + AutomationCompositionState.UNINITIALISED, DeployState.UNDEPLOYED, null); + }).hasMessageMatching("lockState" + NULL_ERROR); + assertNotNull(new JpaAutomationCompositionElement()); assertNotNull(new JpaAutomationCompositionElement("key", "key")); assertNotNull(new JpaAutomationCompositionElement("key", "key", - new PfConceptKey(), AutomationCompositionState.UNINITIALISED)); + new PfConceptKey(), AutomationCompositionState.UNINITIALISED, DeployState.UNDEPLOYED, LockState.LOCKED)); } @Test @@ -189,6 +212,16 @@ class JpaAutomationCompositionElementTest { testJpaAutomationCompositionElement.setState(AutomationCompositionState.UNINITIALISED); assertEquals(0, testJpaAutomationCompositionElement.compareTo(otherJpaAutomationCompositionElement)); + testJpaAutomationCompositionElement.setDeployState(DeployState.DEPLOYED); + assertNotEquals(0, testJpaAutomationCompositionElement.compareTo(otherJpaAutomationCompositionElement)); + testJpaAutomationCompositionElement.setDeployState(DeployState.UNDEPLOYED); + assertEquals(0, testJpaAutomationCompositionElement.compareTo(otherJpaAutomationCompositionElement)); + + testJpaAutomationCompositionElement.setLockState(LockState.UNLOCKED); + assertNotEquals(0, testJpaAutomationCompositionElement.compareTo(otherJpaAutomationCompositionElement)); + testJpaAutomationCompositionElement.setLockState(LockState.LOCKED); + assertEquals(0, testJpaAutomationCompositionElement.compareTo(otherJpaAutomationCompositionElement)); + assertEquals(0, testJpaAutomationCompositionElement.compareTo(otherJpaAutomationCompositionElement)); testJpaAutomationCompositionElement.setParticipantId(UUID.randomUUID().toString()); assertNotEquals(0, testJpaAutomationCompositionElement.compareTo(otherJpaAutomationCompositionElement)); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java index 2164f5782..30e225995 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. + * Copyright (C) 2021-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,8 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +import org.onap.policy.clamp.models.acm.concepts.DeployState; +import org.onap.policy.clamp.models.acm.concepts.LockState; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.models.base.PfConceptKey; @@ -58,30 +60,43 @@ class JpaAutomationCompositionTest { }).hasMessageMatching("copyConcept is marked .*ull but is null"); assertThatThrownBy(() -> { - new JpaAutomationComposition(null, null, null, null, null); + new JpaAutomationComposition(null, null, null, null, null, null, null); }).hasMessageMatching(NULL_INSTANCE_ID_ERROR); assertThatThrownBy(() -> { - new JpaAutomationComposition(INSTANCE_ID, null, null, null, new ArrayList<>()); + new JpaAutomationComposition(INSTANCE_ID, null, null, null, new ArrayList<>(), + DeployState.UNDEPLOYED, LockState.LOCKED); }).hasMessageMatching("key" + NULL_TEXT_ERROR); assertThatThrownBy(() -> { new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), null, - AutomationCompositionState.UNINITIALISED, null); + AutomationCompositionState.UNINITIALISED, new ArrayList<>(), + DeployState.UNDEPLOYED, LockState.LOCKED); }).hasMessageMatching("compositionId" + NULL_TEXT_ERROR); assertThatThrownBy(() -> { - new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID.toString(), null, null); + new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID.toString(), null, + new ArrayList<>(), DeployState.UNDEPLOYED, LockState.LOCKED); }).hasMessageMatching("state" + NULL_TEXT_ERROR); assertThatThrownBy(() -> { new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID.toString(), - AutomationCompositionState.UNINITIALISED, null); + AutomationCompositionState.UNINITIALISED, null, DeployState.UNDEPLOYED, LockState.LOCKED); }).hasMessageMatching("elements" + NULL_TEXT_ERROR); + assertThatThrownBy(() -> { + new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID.toString(), + AutomationCompositionState.UNINITIALISED, new ArrayList<>(), null, LockState.LOCKED); + }).hasMessageMatching("deployState" + NULL_TEXT_ERROR); + + assertThatThrownBy(() -> { + new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID.toString(), + AutomationCompositionState.UNINITIALISED, new ArrayList<>(), DeployState.UNDEPLOYED, null); + }).hasMessageMatching("lockState" + NULL_TEXT_ERROR); + assertNotNull(new JpaAutomationComposition()); assertNotNull(new JpaAutomationComposition(INSTANCE_ID, new PfConceptKey(), COMPOSITION_ID.toString(), - AutomationCompositionState.UNINITIALISED, new ArrayList<>())); + AutomationCompositionState.UNINITIALISED, new ArrayList<>(), DeployState.UNDEPLOYED, LockState.LOCKED)); } @Test diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java index 784f1cfde..b479f022f 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -89,6 +90,24 @@ class AcDefinitionProviderTest { var result = acDefinitionProvider.createAutomationCompositionDefinition(inputServiceTemplate); assertThat(result.getServiceTemplate()).isEqualTo(docServiceTemplate.toAuthorative()); + assertThat(result.getServiceTemplate().getMetadata() != null); + } + + @Test + void testCreateServiceTemplateWithMetadata() { + var docServiceTemplate = new DocToscaServiceTemplate(inputServiceTemplate); + var acmDefinition = getAcDefinition(docServiceTemplate); + + var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class); + when(acmDefinitionRepository.save(any(JpaAutomationCompositionDefinition.class))) + .thenReturn(new JpaAutomationCompositionDefinition(acmDefinition)); + + var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository); + inputServiceTemplate.setMetadata(new HashMap<>()); + var result = acDefinitionProvider.createAutomationCompositionDefinition(inputServiceTemplate); + + assertThat(result.getServiceTemplate()).isEqualTo(docServiceTemplate.toAuthorative()); + assertThat(result.getServiceTemplate().getMetadata() != null); } @Test @@ -191,6 +210,34 @@ class AcDefinitionProviderTest { assertThat(result.get(0)).isEqualTo(acmDefinition.getServiceTemplate()); } + @Test + void testGetServiceTemplateNulls() { + var docServiceTemplate = new DocToscaServiceTemplate(inputServiceTemplate); + var acmDefinition = getAcDefinition(docServiceTemplate); + var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class); + when(acmDefinitionRepository.findAll(Mockito.<Example<JpaAutomationCompositionDefinition>>any())) + .thenReturn(List.of(new JpaAutomationCompositionDefinition(acmDefinition))); + + var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository); + var result = acDefinitionProvider.getServiceTemplateList(null, + inputServiceTemplate.getVersion()); + + assertThat(result).hasSize(1); + assertThat(result.get(0)).isEqualTo(acmDefinition.getServiceTemplate()); + + result = acDefinitionProvider.getServiceTemplateList(inputServiceTemplate.getName(), + null); + + assertThat(result).hasSize(1); + assertThat(result.get(0)).isEqualTo(acmDefinition.getServiceTemplate()); + + result = acDefinitionProvider.getServiceTemplateList(null, + null); + + assertThat(result).hasSize(0); + assertThat(result.isEmpty()); + } + private AutomationCompositionDefinition getAcDefinition(DocToscaServiceTemplate docServiceTemplate) { var acmDefinition = new AutomationCompositionDefinition(); acmDefinition.setCompositionId(UUID.randomUUID()); |