diff options
author | yongqiangliu312 <yongqiang.liu@nokia-sbell.com> | 2020-01-27 10:40:41 +0800 |
---|---|---|
committer | Patrick Brady <patrick.brady@att.com> | 2020-01-29 14:18:45 -0800 |
commit | e4c07d4c7eb3105bc6a20eee00fdca592f0cf59b (patch) | |
tree | 74e8abcb92df09514c01b6ca041e5643feec33e8 /appc-provider | |
parent | b5fe8a69e90b950c07dc11af481eab7e9bab52c6 (diff) |
add new action ConfigScaleIn
Change-Id: Iae4bb797c4e86f66e5e3101fc6715fc2c2be470f
Issue-ID: APPC-1760
Signed-off-by: Taka Cho <takamune.cho@att.com>
Signed-off-by: Patrick Brady <patrick.brady@att.com>
Diffstat (limited to 'appc-provider')
5 files changed, 330 insertions, 3 deletions
diff --git a/appc-provider/appc-provider-bundle/src/main/java/org/onap/appc/provider/AppcProviderLcm.java b/appc-provider/appc-provider-bundle/src/main/java/org/onap/appc/provider/AppcProviderLcm.java index d37da6529..dc81f7e71 100644 --- a/appc-provider/appc-provider-bundle/src/main/java/org/onap/appc/provider/AppcProviderLcm.java +++ b/appc-provider/appc-provider-bundle/src/main/java/org/onap/appc/provider/AppcProviderLcm.java @@ -61,6 +61,7 @@ import org.onap.appc.provider.lcm.service.LicenseManagementService; import org.onap.appc.provider.lcm.service.StartTraffic; import org.onap.appc.provider.lcm.service.StatusTraffic; import org.onap.appc.provider.lcm.service.StopTraffic; +import org.onap.appc.provider.lcm.service.ConfigScaleInService; import org.onap.appc.provider.lcm.util.RequestInputBuilder; import org.onap.appc.provider.lcm.util.ValidationService; import org.onap.appc.requesthandler.objects.RequestHandlerInput; @@ -775,6 +776,14 @@ public class AppcProviderLcm extends AbstractBaseUtils implements AutoCloseable, RpcResult<ConfigScaleOutOutput> result = RpcResultBuilder.<ConfigScaleOutOutput> status(true).withResult(outputBuilder.build()).build(); return Futures.immediateFuture(result); } + + @Override + public ListenableFuture<RpcResult<ConfigScaleInOutput>> configScaleIn(ConfigScaleInInput input) { + logger.debug("Input received : " + input.toString()); + ConfigScaleInOutputBuilder outputBuilder = new ConfigScaleInService().process(input); + RpcResult<ConfigScaleInOutput> result = RpcResultBuilder.<ConfigScaleInOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } @Override public ListenableFuture<RpcResult<PostEvacuateOutput>> postEvacuate(PostEvacuateInput input) { diff --git a/appc-provider/appc-provider-bundle/src/main/java/org/onap/appc/provider/lcm/service/ConfigScaleInService.java b/appc-provider/appc-provider-bundle/src/main/java/org/onap/appc/provider/lcm/service/ConfigScaleInService.java new file mode 100644 index 000000000..c190b0623 --- /dev/null +++ b/appc-provider/appc-provider-bundle/src/main/java/org/onap/appc/provider/lcm/service/ConfigScaleInService.java @@ -0,0 +1,106 @@ + +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2019 Nokia + * ============================================================================= + * 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.appc.provider.lcm.service; + +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.Action; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.ConfigScaleInInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.ConfigScaleInOutputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.Payload; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.action.identifiers.ActionIdentifiers; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.common.header.CommonHeader; +import org.onap.appc.executor.objects.LCMCommandStatus; +import org.onap.appc.requesthandler.objects.RequestHandlerInput; +import org.onap.appc.util.JsonUtil; +import java.io.IOException; +import java.util.Map; + +public class ConfigScaleInService extends AbstractBaseService { + + public ConfigScaleInService() { + super(Action.ConfigScaleIn); + logger.debug("ConfigScaleInService starts"); + } + + public ConfigScaleInOutputBuilder process(ConfigScaleInInput input) { + CommonHeader commonHeader = input.getCommonHeader(); + ActionIdentifiers actionIdentifiers = input.getActionIdentifiers(); + Payload payload = input.getPayload(); + + validate(commonHeader, input.getAction(), actionIdentifiers, payload); + if (status == null) { + proceedAction(commonHeader, actionIdentifiers, payload); + } + + ConfigScaleInOutputBuilder outputBuilder = new ConfigScaleInOutputBuilder(); + outputBuilder.setStatus(status); + outputBuilder.setCommonHeader(input.getCommonHeader()); + return outputBuilder; + } + + + void validate(CommonHeader commonHeader, + Action action, + ActionIdentifiers actionIdentifiers, + Payload payload) { + status = validateVnfId(commonHeader, action, actionIdentifiers); + if (status != null) { + return; + } + + // validate payload + String keyName = "payload"; + if (payload == null) { + status = buildStatusForParamName(LCMCommandStatus.MISSING_MANDATORY_PARAMETER, keyName); + return; + } +// if (payload !=null) { + String payloadString = payload.getValue(); + status = validateMustHaveParamValue( + payloadString == null ? payloadString : payloadString.trim(), "payload"); + if (status != null) { + return; + } + + try { + Map<String, String> payloadMap = JsonUtil.convertJsonStringToFlatMap(payloadString); + validateMustHaveParamValue(payloadMap.get(keyName), keyName); + validateMustHaveParamValue(payloadMap.get("payload.request-parameters.vf-module-id"), "vf-module-id"); + } catch (IOException e) { + logger.error(String.format("ConfigScaleInService (%s) got IOException when converting payload", rpcName), e); + status = buildStatusForErrorMsg(LCMCommandStatus.UNEXPECTED_ERROR, e.getMessage()); + } + } + +// } + + void proceedAction(CommonHeader commonHeader, + ActionIdentifiers actionIdentifiers, + Payload payload) { + RequestHandlerInput requestHandlerInput = + getRequestHandlerInput(commonHeader, actionIdentifiers, payload, this.getClass().getName()); + if (requestHandlerInput != null) { + executeAction(requestHandlerInput); + } + } +} + diff --git a/appc-provider/appc-provider-bundle/src/test/java/org/onap/appc/provider/AppcProviderLcmTest.java b/appc-provider/appc-provider-bundle/src/test/java/org/onap/appc/provider/AppcProviderLcmTest.java index 047c7f213..082f04982 100644 --- a/appc-provider/appc-provider-bundle/src/test/java/org/onap/appc/provider/AppcProviderLcmTest.java +++ b/appc-provider/appc-provider-bundle/src/test/java/org/onap/appc/provider/AppcProviderLcmTest.java @@ -4,7 +4,7 @@ * ================================================================================ * Copyright (C) 2018-2019 Ericsson * ================================================================================ - * Modifications Copyright (C) 2019 Orange + * Modifications Copyright (C) 2019 Orange Nokia * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82,6 +82,7 @@ import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.UpgradeBackupInp import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.UpgradePostCheckInput; import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.UpgradePreCheckInput; import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.UpgradeSoftwareInput; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.ConfigScaleInInput; import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.ZULU; import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.action.identifiers.ActionIdentifiersBuilder; import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.common.header.CommonHeaderBuilder; @@ -738,6 +739,15 @@ public class AppcProviderLcmTest { underTest.close(); Mockito.verify(rpcRegistration).close(); } + + @Test + public void configScaleInTest() { + ConfigScaleInInput configScaleInInput = mock(ConfigScaleInInput.class); + Mockito.doReturn(Action.ConfigScaleIn).when(configScaleInInput).getAction(); + Mockito.doReturn(getCommonHeaderBuilder().build()).when(configScaleInInput) + .getCommonHeader(); + assertTrue(underTest.configScaleIn(configScaleInInput).isDone()); + } private CommonHeaderBuilder getCommonHeaderBuilder() { CommonHeaderBuilder headerBuilder = new CommonHeaderBuilder(); diff --git a/appc-provider/appc-provider-bundle/src/test/java/org/onap/appc/provider/lcm/service/ConfigScaleInServiceTest.java b/appc-provider/appc-provider-bundle/src/test/java/org/onap/appc/provider/lcm/service/ConfigScaleInServiceTest.java new file mode 100644 index 000000000..63d154ca8 --- /dev/null +++ b/appc-provider/appc-provider-bundle/src/test/java/org/onap/appc/provider/lcm/service/ConfigScaleInServiceTest.java @@ -0,0 +1,174 @@ + +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2019 Nokia. + * ================================================================================ + * 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.appc.provider.lcm.service; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.internal.util.reflection.Whitebox; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.appc.util.JsonUtil; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.*; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.action.identifiers.ActionIdentifiers; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.onap.appc.lcm.rev160108.status.Status; +import org.onap.appc.domainmodel.lcm.ResponseContext; +import org.onap.appc.executor.objects.LCMCommandStatus; +import org.onap.appc.requesthandler.objects.RequestHandlerOutput; +import org.onap.appc.requesthandler.objects.RequestHandlerInput; + +import java.util.Map; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; + +@RunWith(MockitoJUnitRunner.class) +public class ConfigScaleInServiceTest { + private final Action myAction = Action.ConfigScaleIn; + private final String PAYLOAD_STRING = "{\"A\":\"A-value\",\"B\":{\"C\":\"B.C-value\",\"D\":\"B.D-value\"}}"; + private ConfigScaleInInput mockInput = mock(ConfigScaleInInput.class); + private CommonHeader mockCommonHeader = mock(CommonHeader.class); + private ActionIdentifiers mockAI = mock(ActionIdentifiers.class); + private Payload mockPayload = mock(Payload.class); + + private ConfigScaleInService configscaleinServiceAction; + @Before + public void setUp() throws Exception { + + configscaleinServiceAction = spy(new ConfigScaleInService()); + } + + @Test + public void testProcess() throws Exception { + // test error occurs in validation + ConfigScaleInOutputBuilder outputBuilder = configscaleinServiceAction.process(mockInput); + Mockito.verify(configscaleinServiceAction, times(0)).proceedAction(any(),any(),any()); + Assert.assertTrue("Should not have commonHeader as we did not mock it",outputBuilder.getCommonHeader() == null); + Assert.assertEquals("should return missing parameter status", + Integer.valueOf(LCMCommandStatus.MISSING_MANDATORY_PARAMETER.getResponseCode()), + outputBuilder.getStatus().getCode()); + + // make validation pass + Mockito.doReturn(mockCommonHeader).when(mockInput).getCommonHeader(); + Mockito.doReturn(mockPayload).when(mockInput).getPayload(); + Mockito.doReturn(PAYLOAD_STRING).when(mockPayload).getValue(); + // to make validation pass + ZULU zuluTimeStamp = new ZULU("2019-12-06T21:44:00.35Z"); + Mockito.doReturn(zuluTimeStamp).when(mockCommonHeader).getTimestamp(); + Mockito.doReturn("api ver").when(mockCommonHeader).getApiVer(); + Mockito.doReturn("orignator Id").when(mockCommonHeader).getOriginatorId(); + Mockito.doReturn("request Id").when(mockCommonHeader).getRequestId(); + + Mockito.doReturn(myAction).when(mockInput).getAction(); + Mockito.doReturn(mockAI).when(mockInput).getActionIdentifiers(); + Mockito.doReturn("vnfId").when(mockAI).getVnfId(); + + // test processAction return without error + RequestExecutor mockExecutor = mock(RequestExecutor.class); + // whenNew(RequestExecutor.class).withNoArguments().thenReturn(mockExecutor); + + RequestHandlerOutput mockOutput = mock(RequestHandlerOutput.class); + Mockito.doReturn(mockOutput).when(mockExecutor).executeRequest(any()); + + ResponseContext mockResponseContext = mock(ResponseContext.class); + Mockito.doReturn(mockResponseContext).when(mockOutput).getResponseContext(); + + org.onap.appc.domainmodel.lcm.Status mockStatus = mock(org.onap.appc.domainmodel.lcm.Status.class); + Integer successCode = Integer.valueOf(LCMCommandStatus.SUCCESS.getResponseCode()); + Mockito.doReturn(successCode).when(mockStatus).getCode(); + Mockito.doReturn(mockStatus).when(mockResponseContext).getStatus(); + RequestHandlerInput requestHandlerInputInput = mock(RequestHandlerInput.class); + AbstractBaseService abstractBaseService = mock(AbstractBaseService.class); + Mockito.when(abstractBaseService.executeAction(requestHandlerInputInput)).thenReturn(mockOutput); + try { + outputBuilder = configscaleinServiceAction.process(mockInput); + }catch(Exception e){ + Assert.assertTrue(true); + } + Assert.assertTrue("Should have commonHeader",outputBuilder.getCommonHeader() == null); + Assert.assertEquals("should return success status", new Integer(302), outputBuilder.getStatus().getCode()); + } + + @Test + public void testValidate() throws Exception { + configscaleinServiceAction.validate(mockCommonHeader, Action.ConfigScaleIn, mockAI,mockPayload); + Status status = (Status) Whitebox.getInternalState(configscaleinServiceAction, "status"); + Assert.assertEquals("should return missing parameter", + Integer.valueOf(LCMCommandStatus.MISSING_MANDATORY_PARAMETER.getResponseCode()), status.getCode()); + Mockito.verify(configscaleinServiceAction, times(0)).buildStatusForParamName(any(), any()); + Mockito.verify(configscaleinServiceAction, times(0)).buildStatusForErrorMsg(any(), any()); + + ZULU mockTimeStamp = mock(ZULU.class); + Mockito.doReturn(mockTimeStamp).when(mockCommonHeader).getTimestamp(); + Mockito.doReturn("api ver").when(mockCommonHeader).getApiVer(); + Mockito.doReturn("orignator Id").when(mockCommonHeader).getOriginatorId(); + Mockito.doReturn("request Id").when(mockCommonHeader).getRequestId(); + + // test empty action + configscaleinServiceAction.validate(mockCommonHeader, Action.ConfigScaleIn, mockAI,mockPayload); + status = (Status) Whitebox.getInternalState(configscaleinServiceAction, "status"); + Assert.assertEquals("Should return missing parameter for action", + Integer.valueOf(LCMCommandStatus.MISSING_MANDATORY_PARAMETER.getResponseCode()), status.getCode()); + + // test empty ActionIdentifier + configscaleinServiceAction.validate(mockCommonHeader, Action.ConfigScaleIn, mockAI,mockPayload); + status = (Status) Whitebox.getInternalState(configscaleinServiceAction, "status"); + Assert.assertEquals("should return missing parameter", + Integer.valueOf(LCMCommandStatus.MISSING_MANDATORY_PARAMETER.getResponseCode()), status.getCode()); + + // test Invalid VNF_ID + Mockito.doReturn("").when(mockAI).getVnfId(); + configscaleinServiceAction.validate(mockCommonHeader, Action.ConfigScaleIn, mockAI,mockPayload); + status = (Status) Whitebox.getInternalState(configscaleinServiceAction, "status"); + Assert.assertEquals("should return invalid parameter", + Integer.valueOf(LCMCommandStatus.INVALID_INPUT_PARAMETER.getResponseCode()), status.getCode()); + + // test null payload + Mockito.doReturn("vnfId").when(mockAI).getVnfId(); + configscaleinServiceAction.validate(mockCommonHeader, Action.ConfigScaleIn, mockAI, null); + Mockito.verify(configscaleinServiceAction, times(1)).validateExcludedActIds(any(), any()); + status = (Status) Whitebox.getInternalState(configscaleinServiceAction, "status"); + Assert.assertEquals("should return missing parameter", + Integer.valueOf(LCMCommandStatus.MISSING_MANDATORY_PARAMETER.getResponseCode()), status.getCode()); + + // test empty payload + + Mockito.doReturn("").when(mockPayload).getValue(); + configscaleinServiceAction.validate(mockCommonHeader, Action.ConfigScaleIn, mockAI, mockPayload); + status = (Status) Whitebox.getInternalState(configscaleinServiceAction, "status"); + Assert.assertEquals("should return invalid parameter", + Integer.valueOf(LCMCommandStatus.INVALID_INPUT_PARAMETER.getResponseCode()), status.getCode()); + + // test space payload + Mockito.doReturn(" ").when(mockPayload).getValue(); + configscaleinServiceAction.validate(mockCommonHeader, Action.ConfigScaleIn, mockAI, mockPayload); + status = (Status) Whitebox.getInternalState(configscaleinServiceAction, "status"); + Assert.assertEquals("should return invalid parameter", + Integer.valueOf(LCMCommandStatus.INVALID_INPUT_PARAMETER.getResponseCode()), status.getCode()); + } +} + diff --git a/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang b/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang index c060582fa..99de6c4d2 100644 --- a/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang +++ b/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang @@ -6,7 +6,7 @@ * ================================================================================ * Copyright (C) 2017 Amdocs * ================================================================================ - * Modifications Copyright (C) 2018-2019 Orange + * Modifications Copyright (C) 2018-2019 Orange Nokia * ============================================================================= * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -138,6 +138,7 @@ module appc-provider-lcm { enum "StartTraffic"; enum "StatusTraffic"; enum "StopTraffic"; + enum "ConfigScaleIn"; } description "The action to be taken by APP-C, e.g. Restart, Rebuild, Migrate"; } @@ -1755,6 +1756,33 @@ module appc-provider-lcm { } /********************************************************************************** - * Additional RPCs added here... + * Define the VNF ConfigScaleIn service + **********************************************************************************/ + rpc config-scale-in { + description "An operation to Modify the configuration or other action to support + a ConfigScaleIn of a VNF."; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + leaf payload { + type payload; + mandatory false; + } + } + } + /********************************************************************************** + * Additional RPCs added here... **********************************************************************************/ } |