diff options
11 files changed, 234 insertions, 17 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java index f2397602b..4d3d37236 100644 --- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java @@ -52,6 +52,9 @@ public class ControlLoop extends ToscaEntity implements Comparable<ControlLoop> private Map<UUID, ControlLoopElement> elements; + @NonNull + private Boolean primed = false; + @Override public String getType() { return definition.getName(); @@ -73,6 +76,7 @@ public class ControlLoop extends ToscaEntity implements Comparable<ControlLoop> this.state = otherControlLoop.state; this.orderedState = otherControlLoop.orderedState; this.elements = PfUtils.mapMap(otherControlLoop.elements, ControlLoopElement::new); + this.primed = otherControlLoop.primed; } @Override diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaControlLoop.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaControlLoop.java index 2a2cde2ae..756c4f1bf 100644 --- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaControlLoop.java +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaControlLoop.java @@ -91,6 +91,9 @@ public class JpaControlLoop extends PfConcept implements PfAuthorative<ControlLo @Column private String description; + @Column + private Boolean primed; + // @formatter:off @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @NotNull @@ -141,6 +144,7 @@ public class JpaControlLoop extends PfConcept implements PfAuthorative<ControlLo this.orderedState = copyConcept.orderedState; this.description = copyConcept.description; this.elements = PfUtils.mapMap(copyConcept.elements, JpaControlLoopElement::new, new LinkedHashMap<>(0)); + this.primed = copyConcept.primed; } /** @@ -163,6 +167,7 @@ public class JpaControlLoop extends PfConcept implements PfAuthorative<ControlLo controlLoop.setOrderedState(orderedState != null ? orderedState : state.asOrderedState()); controlLoop.setDescription(description); controlLoop.setElements(PfUtils.mapMap(elements, JpaControlLoopElement::toAuthorative, new LinkedHashMap<>(0))); + controlLoop.setPrimed(primed); return controlLoop; } @@ -177,6 +182,7 @@ public class JpaControlLoop extends PfConcept implements PfAuthorative<ControlLo this.state = controlLoop.getState(); this.orderedState = controlLoop.getOrderedState(); this.description = controlLoop.getDescription(); + this.primed = controlLoop.getPrimed(); this.elements = new LinkedHashMap<>(controlLoop.getElements().size()); for (Entry<UUID, ControlLoopElement> elementEntry : controlLoop.getElements().entrySet()) { @@ -249,6 +255,10 @@ public class JpaControlLoop extends PfConcept implements PfAuthorative<ControlLo return result; } + result = ObjectUtils.compare(primed, other.primed); + if (result != 0) { + return result; + } return PfUtils.compareObjects(elements, other.elements); } } diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/ControlLoopPrimed.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/ControlLoopPrimed.java new file mode 100644 index 000000000..d6e670060 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/ControlLoopPrimed.java @@ -0,0 +1,32 @@ +/* + * ============LICENSE_START======================================================= + * 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.clamp.controlloop.models.messages.rest.instantiation; + +import lombok.Data; + +@Data +public class ControlLoopPrimed { + + private String name; + + private String version; + + private boolean primed; +} diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/ControlLoopPrimedResponse.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/ControlLoopPrimedResponse.java new file mode 100644 index 000000000..993c6e592 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/rest/instantiation/ControlLoopPrimedResponse.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * 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.clamp.controlloop.models.messages.rest.instantiation; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; +import org.onap.policy.clamp.controlloop.models.messages.rest.GenericNameVersion; +import org.onap.policy.clamp.controlloop.models.messages.rest.SimpleResponse; + + +/** + * Response to provide all primed controlLoops. + */ +@Getter +@Setter +@ToString(callSuper = true) +public class ControlLoopPrimedResponse extends SimpleResponse { + + private List<ControlLoopPrimed> primedControlLoopsList = new ArrayList<>(); +} diff --git a/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaControlLoopTest.java b/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaControlLoopTest.java index ff6cc7619..d705c49b5 100644 --- a/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaControlLoopTest.java +++ b/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/concepts/JpaControlLoopTest.java @@ -240,6 +240,11 @@ class JpaControlLoopTest { testJpaControlLoop.setDescription(null); assertEquals(0, testJpaControlLoop.compareTo(otherJpaControlLoop)); + testJpaControlLoop.setPrimed(true); + assertNotEquals(0, testJpaControlLoop.compareTo(otherJpaControlLoop)); + testJpaControlLoop.setPrimed(false); + assertEquals(0, testJpaControlLoop.compareTo(otherJpaControlLoop)); + assertEquals(testJpaControlLoop, new JpaControlLoop(testJpaControlLoop)); } diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java index 9054788f9..880514110 100644 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java @@ -76,33 +76,36 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { * * @param controlLoopElementId the ID of the control loop element * @param currentState the current state of the control loop element - * @param newState the state to which the control loop element is changing to + * @param orderedState the state to which the control loop element is changing to * @throws PfModelException in case of an exception */ @Override public void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId, UUID controlLoopElementId, ControlLoopState currentState, - ControlLoopOrderedState newState) throws PfModelException { - switch (newState) { + ControlLoopOrderedState orderedState) throws PfModelException { + switch (orderedState) { case UNINITIALISED: try { - deletePolicyData(controlLoopId, controlLoopElementId, newState); + deletePolicyData(controlLoopId, controlLoopElementId, orderedState); + intermediaryApi.updateControlLoopElementState(controlLoopId, + controlLoopElementId, orderedState, ControlLoopState.UNINITIALISED, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); } catch (PfModelRuntimeException e) { LOGGER.debug("Deleting policy data failed", e); } break; case PASSIVE: intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.PASSIVE, + controlLoopElementId, orderedState, ControlLoopState.PASSIVE, ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); break; case RUNNING: intermediaryApi.updateControlLoopElementState(controlLoopId, - controlLoopElementId, newState, ControlLoopState.RUNNING, + controlLoopElementId, orderedState, ControlLoopState.RUNNING, ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); break; default: - LOGGER.debug("Unknown orderedstate {}", newState); + LOGGER.debug("Unknown orderedstate {}", orderedState); break; } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java index 8bdf91824..30a06ba22 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java @@ -103,9 +103,11 @@ public class ControlLoopHandler { return null; } + // Update states of ControlLoopElement in controlLoopMap for (var controlLoop : controlLoopMap.values()) { var element = controlLoop.getElements().get(id); if (element != null) { + element.setOrderedState(orderedState); element.setState(newState); } var checkOpt = controlLoop.getElements().values().stream() @@ -116,6 +118,7 @@ public class ControlLoopHandler { } } + // Update states of ControlLoopElement in elementsOnThisParticipant var clElement = elementsOnThisParticipant.get(id); if (clElement != null) { var controlLoopStateChangeAck = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK); @@ -339,16 +342,16 @@ public class ControlLoopHandler { return; } - for (var clElementListener : listeners) { - try { - for (var element : controlLoop.getElements().values()) { - clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), element.getId(), - element.getState(), orderedState); + controlLoop.getElements().values().stream().forEach(clElement -> { + for (var clElementListener : listeners) { + try { + clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), + clElement.getId(), clElement.getState(), orderedState); + } catch (PfModelException e) { + LOGGER.debug("Control loop element update failed {}", controlLoop.getDefinition()); } - } catch (PfModelException e) { - LOGGER.debug("Control loop element update failed {}", controlLoop.getDefinition()); } - } + }); } /** diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java index dc40cc274..28558cc02 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java @@ -47,6 +47,8 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.messages.rest.GenericNameVersion; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopOrderStateResponse; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopPrimed; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopPrimedResponse; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstancePropertiesResponse; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; @@ -389,6 +391,33 @@ public class ControlLoopInstantiationProvider { /** * Saves Instance Properties and Control Loop. + * Gets a list of control loops which are primed or de-primed. + * + * @param name the name of the control loop to get, null for all control loops + * @param version the version of the control loop to get, null for all control loops + * @return a list of Instantiation Command + * @throws PfModelException on errors getting control loops + */ + public ControlLoopPrimedResponse getControlLoopPriming(String name, String version) + throws PfModelException { + + List<ControlLoop> controlLoops = controlLoopProvider.getControlLoops(name, version); + + var response = new ControlLoopPrimedResponse(); + + controlLoops.forEach(controlLoop -> { + var primed = new ControlLoopPrimed(); + primed.setName(controlLoop.getName()); + primed.setVersion(controlLoop.getVersion()); + primed.setPrimed(controlLoop.getPrimed()); + response.getPrimedControlLoopsList().add(primed); + }); + + return response; + } + + /** + * Creates instance element name. * * @param serviceTemplate the service template * @param controlLoops a list of control loops diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java index 91958f97a..b65d3b784 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java @@ -34,6 +34,7 @@ import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopOrderStateResponse; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopPrimedResponse; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstancePropertiesResponse; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; @@ -571,4 +572,65 @@ public class InstantiationController extends AbstractRestController { return ResponseEntity.ok().body(provider.getInstantiationOrderState(name, version)); } + + /** + * Queries Primed/De-Primed status of a control loop. + * + * @param requestId request ID used in ONAP logging + * @param name the name of the control loop to get, null for all control loops + * @param version the version of the control loop to get, null for all control loops + * @return the control loops + * @throws PfModelException on errors getting priming of control loop + */ + // @formatter:off + @GetMapping(value = "/controlLoopPriming", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query priming details of the requested control loops", + notes = "Queries priming details of the requested control loops, returning primed/deprimed control loops", + response = ControlLoopPrimedResponse.class, + tags = {TAGS}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader( + name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = { + @Extension + ( + name = EXTENSION_NAME, + properties = { + @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity<ControlLoopPrimedResponse> getControlLoopPriming( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = false) @RequestParam( + value = "name", + required = false) String name, + @ApiParam(value = "Control Loop definition version", required = false) @RequestParam( + value = "version", + required = false) String version) + throws PfModelException { + + return ResponseEntity.ok().body(provider.getControlLoopPriming(name, version)); + } } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java index dbc2c4ea6..c4ca568f7 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java @@ -258,7 +258,8 @@ public class SupervisionHandler { var controlLoop = controlLoopProvider.getControlLoop(controlLoopAckMessage.getControlLoopId()); if (controlLoop != null) { var updated = updateState(controlLoop, controlLoopAckMessage - .getControlLoopResultMap().entrySet()); + .getControlLoopResultMap().entrySet()) + || setPrimed(controlLoop); if (updated) { controlLoopProvider.updateControlLoop(controlLoop); } @@ -284,6 +285,23 @@ public class SupervisionHandler { return updated; } + private boolean setPrimed(ControlLoop controlLoop) { + var clElements = controlLoop.getElements().values(); + if (clElements != null) { + Boolean primedFlag = true; + var checkOpt = controlLoop.getElements().values().stream() + .filter(clElement -> (!clElement.getState().equals(ControlLoopState.PASSIVE) + || !clElement.getState().equals(ControlLoopState.RUNNING))).findAny(); + if (checkOpt.isEmpty()) { + primedFlag = false; + } + controlLoop.setPrimed(primedFlag); + return true; + } + + return false; + } + /** * Supervise a control loop, performing whatever actions need to be performed on the control loop. * @@ -410,7 +428,7 @@ public class SupervisionHandler { var participant = new Participant(); participant.setName(participantStatusMessage.getParticipantId().getName()); participant.setVersion(participantStatusMessage.getParticipantId().getVersion()); - participant.setDefinition(new ToscaConceptIdentifier("unknown", "0.0.0")); + participant.setDefinition(participantStatusMessage.getParticipantId()); participant.setParticipantState(participantStatusMessage.getState()); participant.setHealthStatus(participantStatusMessage.getHealthStatus()); diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java index a6756eece..42e4ddee2 100644 --- a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java @@ -36,6 +36,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopPrimedResponse; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; import org.onap.policy.clamp.controlloop.runtime.instantiation.ControlLoopInstantiationProvider; @@ -80,6 +81,8 @@ class InstantiationControllerTest extends CommonRestController { private static final String INSTANTIATION_COMMAND_ENDPOINT = "instantiation/command"; + private static final String PRIMING_ENDPOINT = "controlLoopPriming"; + private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate(); private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); @@ -174,6 +177,13 @@ class InstantiationControllerTest extends CommonRestController { assertThat(controlLoopsFromDb.getControlLoopList()).hasSize(1); assertEquals(controlLoopFromRsc, controlLoopsFromDb.getControlLoopList().get(0)); } + + invocationBuilder = super.sendRequest(PRIMING_ENDPOINT + "?name=" + + "PMSHInstance0Create" + "&version=" + "1.0.1"); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + ControlLoopPrimedResponse primResponse = rawresp.readEntity(ControlLoopPrimedResponse.class); + assertEquals(false, primResponse.getPrimedControlLoopsList().get(0).isPrimed()); } @Test |