From 081a82bc5ec01291f6cd5aa08f60dc9726435989 Mon Sep 17 00:00:00 2001 From: "raviteja.karumuri" Date: Fri, 12 Aug 2022 18:19:07 +0100 Subject: [SO] Enhance Delete AS Workflow(s) to launch SO CNFM for Delete AS Issue-ID: SO-3886 Signed-off-by: raviteja.karumuri Change-Id: Iab384caa23fb3cc5a9fb0a4783242fe4274aee82 --- .../subprocess/BuildingBlock/CnfDeleteBB.bpmn | 45 +++++-- .../subprocess/BuildingBlock/CnfInstantiateBB.bpmn | 21 +-- .../subprocess/BuildingBlock/MonitorCnfmJob.bpmn | 8 +- .../adapter/cnfm/tasks/CnfDeleteTask.java | 2 +- .../cnfm/tasks/CnfmHttpServiceProvider.java | 2 +- .../cnfm/tasks/CnfmHttpServiceProviderImpl.java | 2 +- .../cnfm/tasks/MonitorCnfmCreateJobTask.java | 141 -------------------- .../adapter/cnfm/tasks/MonitorCnfmJobTask.java | 145 +++++++++++++++++++++ .../adapter/vnfm/tasks/Constants.java | 2 +- 9 files changed, 197 insertions(+), 171 deletions(-) delete mode 100644 bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/MonitorCnfmCreateJobTask.java create mode 100644 bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/MonitorCnfmJobTask.java diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfDeleteBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfDeleteBB.bpmn index da3577ed61..09c9b69ccf 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfDeleteBB.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfDeleteBB.bpmn @@ -8,7 +8,7 @@ Flow_1s7gtbc - Flow_0td4p22 + Flow_00hczi1 Flow_1s7gtbc @@ -22,10 +22,32 @@ SequenceFlow_016sgof Flow_19rm5pn - + + + + + + + + + + + + Flow_0td4p22 + Flow_00hczi1 + + + + + + + + + + @@ -38,24 +60,23 @@ - - - - - - + + + + + - - + + - - + + diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfInstantiateBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfInstantiateBB.bpmn index 6e1996acd8..d2d986e87b 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfInstantiateBB.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/CnfInstantiateBB.bpmn @@ -36,6 +36,7 @@ + Flow_1xcu3yl Flow_149m8py @@ -44,6 +45,10 @@ + + + + @@ -64,31 +69,27 @@ - - - - + + + - - - + + + - - - diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/MonitorCnfmJob.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/MonitorCnfmJob.bpmn index be683b9ca6..5fe2401180 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/MonitorCnfmJob.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/MonitorCnfmJob.bpmn @@ -30,14 +30,14 @@ - + SequenceFlow_0etw572 SequenceFlow_0s1plu9 SequenceFlow_153a3kp - ${MonitorCnfmCreateJobTask.hasOperationFinished(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")))} + ${MonitorCnfmJobTask.hasOperationFinished(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")))} @@ -54,12 +54,12 @@ - + SequenceFlow_1i1o9sh SequenceFlow_0bcgtzj - + SequenceFlow_1v4yr3f SequenceFlow_1543qy7 diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfDeleteTask.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfDeleteTask.java index 54b87ec2fe..ac204d448f 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfDeleteTask.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfDeleteTask.java @@ -92,7 +92,7 @@ public class CnfDeleteTask { cnfmHttpServiceProvider.invokeTerminateAsRequest(asInstanceId, terminateAsRequest); execution.setVariable(CNFM_REQUEST_STATUS_CHECK_URL, terminateStatusCheck.orElseThrow(() -> new NoSuchElementException("Status check url Not found"))); - execution.setVariable(MONITOR_JOB_NAME, "Terminate"); + execution.setVariable(MONITOR_JOB_NAME, "Instantiate"); LOGGER.debug("Successfully invoked CNFM terminate AS request: {}", asInstanceId); } catch (final Exception exception) { diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfmHttpServiceProvider.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfmHttpServiceProvider.java index 06784a0564..e196cc67d7 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfmHttpServiceProvider.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfmHttpServiceProvider.java @@ -39,7 +39,7 @@ public interface CnfmHttpServiceProvider { Optional invokeInstantiateAsRequest(InstantiateAsRequest instantiateAsRequest, String asInstanceId); - Optional getInstantiateOperationJobStatus(final String url); + Optional getOperationJobStatus(final String url); Optional invokeDeleteAsRequest(final String asInstanceId); diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfmHttpServiceProviderImpl.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfmHttpServiceProviderImpl.java index ed0bc3937b..a919503aff 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfmHttpServiceProviderImpl.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/CnfmHttpServiceProviderImpl.java @@ -113,7 +113,7 @@ public class CnfmHttpServiceProviderImpl implements CnfmHttpServiceProvider { } @Override - public Optional getInstantiateOperationJobStatus(final String url) { + public Optional getOperationJobStatus(final String url) { try { final ResponseEntity response = httpServiceProvider.getHttpResponse(url, AsLcmOpOcc.class); diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/MonitorCnfmCreateJobTask.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/MonitorCnfmCreateJobTask.java deleted file mode 100644 index 40a26cfaf9..0000000000 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/MonitorCnfmCreateJobTask.java +++ /dev/null @@ -1,141 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019 Ericsson. All rights reserved. - * ================================================================================ - * Copyright (C) 2019 Samsung - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.so.bpmn.infrastructure.adapter.cnfm.tasks; - -import static org.onap.so.bpmn.infrastructure.adapter.vnfm.tasks.Constants.CREATE_CNF_STATUS_RESPONSE_PARAM_NAME; -import static org.onap.so.bpmn.infrastructure.adapter.vnfm.tasks.Constants.OPERATION_STATUS_PARAM_NAME; - -import java.net.URI; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; -import org.onap.so.bpmn.common.BuildingBlockExecution; -import org.onap.so.client.exception.ExceptionBuilder; -import org.onap.so.cnfm.lcm.model.AsLcmOpOcc; -import org.onap.so.cnfm.lcm.model.AsLcmOpOcc.OperationStateEnum; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - - -/** - * @author sagar.shetty@est.tech - * - */ -@Component -public class MonitorCnfmCreateJobTask { - - private static final String CNFM_REQUEST_STATUS_CHECK_URL = "CnfmStatusCheckUrl"; - private static final String MONITOR_JOB_NAME = "MonitorJobName"; - public static final Set OPERATION_FINISHED_STATES = - Set.of(OperationStateEnum.COMPLETED, OperationStateEnum.FAILED, OperationStateEnum.ROLLED_BACK); - private static final Logger LOGGER = LoggerFactory.getLogger(MonitorCnfmCreateJobTask.class); - protected final ExceptionBuilder exceptionUtil; - private final CnfmHttpServiceProvider cnfmHttpServiceProvider; - - @Autowired - public MonitorCnfmCreateJobTask(final CnfmHttpServiceProvider cnfmHttpServiceProvider, - final ExceptionBuilder exceptionUtil) { - this.cnfmHttpServiceProvider = cnfmHttpServiceProvider; - this.exceptionUtil = exceptionUtil; - } - - /** - * Get the current operation status of instantiation job - * - * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} - */ - public void getCurrentOperationStatus(final BuildingBlockExecution execution) { - try { - LOGGER.debug("Executing getCurrentOperationStatus ..."); - final Optional operationStatusURL = Optional.of(execution.getVariable(CNFM_REQUEST_STATUS_CHECK_URL)); - LOGGER.debug("Executing getCurrentOperationStatus for CNF... :{}", operationStatusURL); - final Optional instantiateOperationJobStatus = - cnfmHttpServiceProvider.getInstantiateOperationJobStatus(String.valueOf(operationStatusURL - .orElseThrow(() -> new NoSuchElementException("Operational Status check url Not found")))); - if (instantiateOperationJobStatus.isPresent()) { - final AsLcmOpOcc asLcmOpOccResponse = instantiateOperationJobStatus.get(); - if (asLcmOpOccResponse.getOperationState() != null) { - final OperationStateEnum operationStatus = asLcmOpOccResponse.getOperationState(); - LOGGER.debug("Operation {} with {} and operation retrieval status : {}", asLcmOpOccResponse.getId(), - operationStatus, asLcmOpOccResponse.getOperationState()); - execution.setVariable(OPERATION_STATUS_PARAM_NAME, asLcmOpOccResponse.getOperationState()); - } - LOGGER.debug("Operation {} without operationStatus and operation retrieval status :{}", - asLcmOpOccResponse.getId(), asLcmOpOccResponse.getOperationState()); - } - execution.setVariable(CREATE_CNF_STATUS_RESPONSE_PARAM_NAME, - instantiateOperationJobStatus.isPresent() ? instantiateOperationJobStatus.get() : " "); - LOGGER.debug("Finished executing getCurrentOperationStatus for CNF..."); - } catch (final Exception exception) { - LOGGER.error("Unable to invoke get current Operation status"); - exceptionUtil.buildAndThrowWorkflowException(execution, 1209, exception); - } - } - - /** - * Log and throw exception on timeout for job status - * - * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} - */ - public void timeOutLogFailure(final BuildingBlockExecution execution) { - String message = "CNF" + execution.getVariable(MONITOR_JOB_NAME) + "operation time out"; - LOGGER.error(message); - exceptionUtil.buildAndThrowWorkflowException(execution, 1205, new Exception(message)); - } - - /** - * Check the final status of instantiation throw exception if not completed successfully - * - * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} - */ - public void checkIfOperationWasSuccessful(final BuildingBlockExecution execution) { - LOGGER.debug("Executing CNF checkIfOperationWasSuccessful ..."); - final OperationStateEnum operationStatusOption = execution.getVariable(OPERATION_STATUS_PARAM_NAME); - final AsLcmOpOcc cnfInstantiateStautusResponse = execution.getVariable(CREATE_CNF_STATUS_RESPONSE_PARAM_NAME); - if ((operationStatusOption == OperationStateEnum.FAILED) - || (operationStatusOption == OperationStateEnum.FAILED_TEMP)) { - final String message = "Unable to" + execution.getVariable(MONITOR_JOB_NAME) + "CNF jobId: " - + (cnfInstantiateStautusResponse != null ? cnfInstantiateStautusResponse.getId() : "null"); - LOGGER.error(message); - exceptionUtil.buildAndThrowWorkflowException(execution, 1206, new Exception()); - } else if ((operationStatusOption == OperationStateEnum.COMPLETED)) { - String monitorJobName = execution.getVariable(MONITOR_JOB_NAME); - LOGGER.debug("Successfully completed CNF {} job", monitorJobName); - } - } - - /** - * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} - * @return boolean to indicate whether job has competed or not - */ - public boolean hasOperationFinished(final BuildingBlockExecution execution) { - LOGGER.debug("Executing hasOperationFinished ..."); - - final OperationStateEnum operationStatusOption = execution.getVariable(OPERATION_STATUS_PARAM_NAME); - if (operationStatusOption != null) { - return OPERATION_FINISHED_STATES.contains(operationStatusOption); - } - LOGGER.debug("OperationStatus is not present yet... "); - LOGGER.debug("Finished executing hasOperationFinished ..."); - return false; - } -} diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/MonitorCnfmJobTask.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/MonitorCnfmJobTask.java new file mode 100644 index 0000000000..72a5cbe1a2 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/cnfm/tasks/MonitorCnfmJobTask.java @@ -0,0 +1,145 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Ericsson. All rights reserved. + * ================================================================================ + * Copyright (C) 2019 Samsung + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.so.bpmn.infrastructure.adapter.cnfm.tasks; + +import static org.onap.so.bpmn.infrastructure.adapter.vnfm.tasks.Constants.CNF_STATUS_RESPONSE_PARAM_NAME; +import static org.onap.so.bpmn.infrastructure.adapter.vnfm.tasks.Constants.OPERATION_STATUS_PARAM_NAME; + +import java.net.URI; +import java.util.Optional; +import java.util.Set; +import org.camunda.bpm.engine.delegate.BpmnError; +import org.onap.so.bpmn.common.BuildingBlockExecution; +import org.onap.so.client.exception.ExceptionBuilder; +import org.onap.so.cnfm.lcm.model.AsLcmOpOcc; +import org.onap.so.cnfm.lcm.model.AsLcmOpOcc.OperationStateEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +/** + * @author sagar.shetty@est.tech + * + */ +@Component +public class MonitorCnfmJobTask { + + private static final String CNFM_REQUEST_STATUS_CHECK_URL = "CnfmStatusCheckUrl"; + private static final String MONITOR_JOB_NAME = "MonitorJobName"; + public static final Set OPERATION_FINISHED_STATES = + Set.of(OperationStateEnum.COMPLETED, OperationStateEnum.FAILED, OperationStateEnum.ROLLED_BACK); + private static final Logger LOGGER = LoggerFactory.getLogger(MonitorCnfmJobTask.class); + protected final ExceptionBuilder exceptionUtil; + private final CnfmHttpServiceProvider cnfmHttpServiceProvider; + + @Autowired + public MonitorCnfmJobTask(final CnfmHttpServiceProvider cnfmHttpServiceProvider, + final ExceptionBuilder exceptionUtil) { + this.cnfmHttpServiceProvider = cnfmHttpServiceProvider; + this.exceptionUtil = exceptionUtil; + } + + /** + * Get the current operation status of cnfm job + * + * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} + */ + public void getCurrentOperationStatus(final BuildingBlockExecution execution) { + try { + LOGGER.debug("Executing getCurrentOperationStatus ..."); + final Optional operationStatusURL = Optional.of(execution.getVariable(CNFM_REQUEST_STATUS_CHECK_URL)); + LOGGER.debug("Executing getCurrentOperationStatus for CNF... :{}", operationStatusURL); + final Optional operationalJobStatus = + cnfmHttpServiceProvider.getOperationJobStatus(String.valueOf(operationStatusURL + .orElseThrow(() -> new BpmnError("Operational Status check url Not found")))); + + final AsLcmOpOcc asLcmOpOccResponse = operationalJobStatus + .orElseThrow(() -> new BpmnError("Unable to get operational Job status from the CNFM")); + + if (asLcmOpOccResponse.getOperationState() != null) { + final OperationStateEnum operationStatus = asLcmOpOccResponse.getOperationState(); + LOGGER.debug("Operation {} with {} and operation retrieval status : {}", asLcmOpOccResponse.getId(), + operationStatus, operationStatus); + execution.setVariable(OPERATION_STATUS_PARAM_NAME, operationStatus); + } else { + LOGGER.debug("Operation {} without operationStatus", asLcmOpOccResponse.getId()); + exceptionUtil.buildAndThrowWorkflowException(execution, 1206, + new Exception("Operation Status is empty")); + } + execution.setVariable(CNF_STATUS_RESPONSE_PARAM_NAME, asLcmOpOccResponse); + LOGGER.debug("Finished executing getCurrentOperationStatus for CNF..."); + } catch (final Exception exception) { + LOGGER.error("Unable to invoke get current Operation status"); + exceptionUtil.buildAndThrowWorkflowException(execution, 1209, exception); + } + } + + /** + * Log and throw exception on timeout for job status + * + * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} + */ + public void timeOutLogFailure(final BuildingBlockExecution execution) { + String message = "CNF" + execution.getVariable(MONITOR_JOB_NAME) + + "operation time out"; + LOGGER.error(message); + exceptionUtil.buildAndThrowWorkflowException(execution, 1205, new Exception(message)); + } + + /** + * Check the final status of cnfm job throw exception if not completed successfully + * + * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} + */ + public void checkIfOperationWasSuccessful(final BuildingBlockExecution execution) { + LOGGER.debug("Executing CNF checkIfOperationWasSuccessful ..."); + final OperationStateEnum operationStatusOption = execution.getVariable(OPERATION_STATUS_PARAM_NAME); + final AsLcmOpOcc cnfStautusResponse = execution.getVariable(CNF_STATUS_RESPONSE_PARAM_NAME); + if ((operationStatusOption == OperationStateEnum.FAILED) + || (operationStatusOption == OperationStateEnum.FAILED_TEMP)) { + final String message = + "Unable to" + execution.getVariable(MONITOR_JOB_NAME) + + "CNF jobId: " + (cnfStautusResponse != null ? cnfStautusResponse.getId() : "null"); + LOGGER.error(message); + exceptionUtil.buildAndThrowWorkflowException(execution, 1206, new Exception()); + } else if ((operationStatusOption == OperationStateEnum.COMPLETED)) { + String monitorJobName = execution.getVariable(MONITOR_JOB_NAME); + LOGGER.debug("Successfully completed CNF {} job", monitorJobName); + } + } + + /** + * @param execution {@link org.onap.so.bpmn.common.DelegateExecutionImpl} + * @return boolean to indicate whether job has competed or not + */ + public boolean hasOperationFinished(final BuildingBlockExecution execution) { + LOGGER.debug("Executing hasOperationFinished ..."); + + final OperationStateEnum operationStatusOption = execution.getVariable(OPERATION_STATUS_PARAM_NAME); + if (operationStatusOption != null) { + return OPERATION_FINISHED_STATES.contains(operationStatusOption); + } + LOGGER.debug("OperationStatus is not present yet... "); + LOGGER.debug("Finished executing hasOperationFinished ..."); + return false; + } +} diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/Constants.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/Constants.java index 326e764321..6360736865 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/Constants.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/Constants.java @@ -33,7 +33,7 @@ public class Constants { public static final String CREATE_VNF_REQUEST_PARAM_NAME = "createVnfRequest"; public static final String CREATE_VNF_RESPONSE_PARAM_NAME = "createVnfResponse"; - public static final String CREATE_CNF_STATUS_RESPONSE_PARAM_NAME = "createCnfStatusResponse"; + public static final String CNF_STATUS_RESPONSE_PARAM_NAME = "cnfStatusResponse"; public static final String INPUT_PARAMETER = "inputParameter"; public static final String DELETE_VNF_RESPONSE_PARAM_NAME = "deleteVnfResponse"; public static final String DELETE_VNF_NODE_STATUS = "deleteVnfNodeStatus"; -- cgit 1.2.3-korg