diff options
Diffstat (limited to 'bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc')
8 files changed, 971 insertions, 0 deletions
diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerAction.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerAction.java new file mode 100644 index 0000000000..9feee14640 --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerAction.java @@ -0,0 +1,182 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.appc; + +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import org.onap.appc.client.lcm.model.Action; +import org.onap.appc.client.lcm.model.Status; +import org.onap.so.bpmn.appc.payload.PayloadClient; +import org.onap.so.bpmn.core.json.JsonUtils; +import org.onap.so.client.appc.ApplicationControllerSupport.StatusCategory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + + +public class ApplicationControllerAction { + protected ApplicationControllerOrchestrator client = new ApplicationControllerOrchestrator(); + private String errorCode = "1002"; + private String errorMessage = "Unable to reach App C Servers"; + private static Logger logger = LoggerFactory.getLogger(ApplicationControllerAction.class); + + public void runAppCCommand(Action action, String msoRequestId, String vnfId, Optional<String> payload, HashMap<String, String> payloadInfo, String controllerType){ + Status appCStatus = null; + try{ + String vnfName = payloadInfo.getOrDefault("vnfName", ""); + String aicIdentity = payloadInfo.getOrDefault("vnfName",""); + String vnfHostIpAddress = payloadInfo.getOrDefault("vnfHostIpAddress",""); + String vmIdList = payloadInfo.getOrDefault("vmIdList", ""); + String vserverIdList = payloadInfo.getOrDefault("vserverIdList", ""); + String identityUrl = payloadInfo.getOrDefault("identityUrl", ""); + switch(action){ + case ResumeTraffic: + appCStatus = resumeTrafficAction(msoRequestId, vnfId, vnfName, controllerType); + break; + case Start: + case Stop: + appCStatus = startStopAction(action, msoRequestId, vnfId, aicIdentity, controllerType); + break; + case Unlock: + case Lock: + appCStatus = client.vnfCommand(action, msoRequestId, vnfId, Optional.empty(), Optional.empty(), controllerType); + break; + case QuiesceTraffic: + appCStatus = quiesceTrafficAction(msoRequestId, vnfId, payload, vnfName, controllerType); + break; + case HealthCheck: + appCStatus = healthCheckAction(msoRequestId, vnfId, vnfName, vnfHostIpAddress, controllerType); + break; + case Snapshot: + String vmIds = JsonUtils.getJsonValue(vmIdList, "vmIds"); + String vserverIds = JsonUtils.getJsonValue(vserverIdList, "vserverIds"); + String vmId = ""; + String vserverId = ""; + ObjectMapper mapper = new ObjectMapper(); + List<String> vmIdJsonList = mapper.readValue(vmIds, new TypeReference<List<String>>(){}); + List<String> vserverIdJsonList = mapper.readValue(vserverIds, new TypeReference<List<String>>(){}); + int i = 0; + while(i < vmIdJsonList.size()){ + vmId = vmIdJsonList.get(i); + vserverId = vserverIdJsonList.get(i); + Optional<String> vserverIdString = Optional.of(vserverId); + appCStatus = snapshotAction(msoRequestId, vnfId, vmId, vserverIdString, identityUrl, controllerType); + i++; + } + break; + case ConfigModify: + case ConfigScaleOut: + appCStatus = payloadAction(action, msoRequestId, vnfId, payload, controllerType); + break; + case UpgradePreCheck: + case UpgradePostCheck: + case UpgradeSoftware: + case UpgradeBackup: + appCStatus = upgradeAction(action,msoRequestId, vnfId, payload, vnfName, controllerType); + break; + default: + errorMessage = "Unable to idenify Action request for AppCClient"; + break; + } + if(appCStatus != null){ + errorCode = Integer.toString(appCStatus.getCode()); + errorMessage = appCStatus.getMessage(); + + } + if(ApplicationControllerSupport.getCategoryOf(appCStatus).equals(StatusCategory.NORMAL)){ + errorCode = "0"; + } + } + catch(JsonProcessingException e){ + logger.error("Incorrect Payload format for action request: {}", action.toString(),e); + errorMessage = e.getMessage(); + } + catch(ApplicationControllerOrchestratorException e){ + logger.error("Error building Appc request: {}",e.getMessage(), e); + errorCode = "1002"; + errorMessage = e.getMessage(); + } + catch (NoSuchMethodError e) { + logger.error( "Error building Appc request: {}", e.getMessage(), e); + errorMessage = e.getMessage(); + } + catch(Exception e){ + logger.error("Error building Appc request: {}", e.getMessage(), e); + errorMessage = e.getMessage(); + } + } + + private Status payloadAction(Action action, String msoRequestId, String vnfId, Optional<String> payload, String controllerType) throws JsonProcessingException, IllegalArgumentException,ApplicationControllerOrchestratorException{ + if(!(payload.isPresent())){ + throw new IllegalArgumentException("Payload is not present for " + action.toString()); + } + return client.vnfCommand(action, msoRequestId, vnfId, Optional.empty(), payload, controllerType); + } + + private Status quiesceTrafficAction(String msoRequestId, String vnfId, Optional<String> payload, String vnfName, String controllerType) throws JsonProcessingException, IllegalArgumentException,ApplicationControllerOrchestratorException{ + if(!(payload.isPresent())){ + throw new IllegalArgumentException("Payload is not present for " + Action.QuiesceTraffic.toString()); + } + payload = PayloadClient.quiesceTrafficFormat(payload, vnfName); + return client.vnfCommand(Action.QuiesceTraffic, msoRequestId, vnfId, Optional.empty(), payload, controllerType); + } + + private Status upgradeAction(Action action, String msoRequestId, String vnfId, Optional<String> payload, String vnfName, String controllerType) throws JsonProcessingException, IllegalArgumentException,ApplicationControllerOrchestratorException{ + if(!(payload.isPresent())){ + throw new IllegalArgumentException("Payload is not present for " + action.toString()); + } + payload = PayloadClient.upgradeFormat(payload, vnfName); + return client.vnfCommand(action, msoRequestId, vnfId, Optional.empty(), payload, controllerType); + } + + private Status resumeTrafficAction(String msoRequestId, String vnfId, String vnfName, String controllerType)throws JsonProcessingException, ApplicationControllerOrchestratorException{ + Optional<String> payload = PayloadClient.resumeTrafficFormat(vnfName); + return client.vnfCommand(Action.ResumeTraffic, msoRequestId, vnfId, Optional.empty(), payload, controllerType); + } + + private Status startStopAction(Action action, String msoRequestId, String vnfId, String aicIdentity, String controllerType)throws JsonProcessingException, ApplicationControllerOrchestratorException{ + Optional<String> payload = PayloadClient.startStopFormat(aicIdentity); + return client.vnfCommand(action, msoRequestId, vnfId, Optional.empty(), payload, controllerType); + } + + private Status healthCheckAction(String msoRequestId, String vnfId, String vnfName, String vnfHostIpAddress, String controllerType)throws JsonProcessingException, ApplicationControllerOrchestratorException{ + Optional<String> payload = PayloadClient.healthCheckFormat(vnfName, vnfHostIpAddress); + return client.vnfCommand(Action.HealthCheck, msoRequestId, vnfId, Optional.empty(), payload, controllerType); + } + + private Status snapshotAction(String msoRequestId, String vnfId, String vmId, Optional<String> vserverId, String identityUrl, String controllerType) throws JsonProcessingException, ApplicationControllerOrchestratorException{ + Optional<String> payload = PayloadClient.snapshotFormat(vmId, identityUrl); + return client.vnfCommand(Action.Snapshot, msoRequestId, vnfId, vserverId, payload, controllerType); + } + + public String getErrorMessage(){ + return errorMessage; + } + + public String getErrorCode(){ + return errorCode; + } +} diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerCallback.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerCallback.java new file mode 100644 index 0000000000..cb3f144cd1 --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerCallback.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.appc; + +import org.onap.appc.client.lcm.api.ResponseHandler; +import org.onap.appc.client.lcm.exceptions.AppcClientException; + +public class ApplicationControllerCallback<T> implements ResponseHandler<T> { + + @Override + public void onResponse(T response) { + + + } + + @Override + public void onException(AppcClientException exception) { + + + } + +} diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerClient.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerClient.java new file mode 100644 index 0000000000..f87ec91440 --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerClient.java @@ -0,0 +1,206 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.appc; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.time.Instant; +import java.util.Properties; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import org.onap.so.bpmn.core.UrnPropertiesReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.onap.appc.client.lcm.api.AppcClientServiceFactoryProvider; +import org.onap.appc.client.lcm.api.AppcLifeCycleManagerServiceFactory; +import org.onap.appc.client.lcm.api.ApplicationContext; +import org.onap.appc.client.lcm.api.LifeCycleManagerStateful; +import org.onap.appc.client.lcm.exceptions.AppcClientException; +import org.onap.appc.client.lcm.model.Action; +import org.onap.appc.client.lcm.model.ActionIdentifiers; +import org.onap.appc.client.lcm.model.CommonHeader; +import org.onap.appc.client.lcm.model.Flags; +import org.onap.appc.client.lcm.model.Flags.Force; +import org.onap.appc.client.lcm.model.Flags.Mode; +import org.onap.appc.client.lcm.model.Payload; +import org.onap.appc.client.lcm.model.Status; +import org.onap.appc.client.lcm.model.ZULU; + +public class ApplicationControllerClient { + + public static final String DEFAULT_CONTROLLER_TYPE = "APPC"; + + private static final String CLIENT_NAME = "MSO"; + + private static final String API_VER = "2.00"; + private static final String ORIGINATOR_ID = "MSO"; + private static final int FLAGS_TTL = 65000; + private static Logger logger = LoggerFactory.getLogger(ApplicationControllerClient.class); + + private ApplicationControllerSupport appCSupport; + + // APPC gave us an API where the controllerType is configured in the + // client object, which is not what we asked for. We asked for an API + // in which the client would have additional methods that could take + // the controllerType as a parameter, so that we would not need to + // maintain multiple client objects. This map should be removed when + // the (hopefully short-term) controllerType becomes obsolete. + + private final String controllerType; + + private static ConcurrentHashMap<String, LifeCycleManagerStateful> appCClients = new ConcurrentHashMap<>(); + + /** + * Creates an ApplicationControllerClient for communication with APP-C. + */ + public ApplicationControllerClient() { + this(DEFAULT_CONTROLLER_TYPE); + } + + /** + * Creates an ApplicationControllerClient for the specified controller type. + * @param controllerType the controller type: "appc" or "sdnc". + */ + public ApplicationControllerClient(String controllerType) { + if (controllerType == null) { + controllerType = DEFAULT_CONTROLLER_TYPE; + } + this.controllerType = controllerType.toUpperCase(); + appCSupport = new ApplicationControllerSupport(); + } + + /** + * Gets the controller type. + * @return the controllertype + */ + public String getControllerType() { + return controllerType; + } + + /** + * Returns the AppC client object associated with this ApplicationControllerClient. + * AppC client objects are shared objects. One is created if it does not exist. + * @return the client object, or null if creation failed + */ + public LifeCycleManagerStateful getAppCClient() { + return appCClients.computeIfAbsent(controllerType, k -> createAppCClient(k)); + } + + protected LifeCycleManagerStateful createAppCClient(String controllerType) { + try { + if (controllerType == null) { + controllerType = DEFAULT_CONTROLLER_TYPE; + } + controllerType = controllerType.toUpperCase(); + return AppcClientServiceFactoryProvider.getFactory(AppcLifeCycleManagerServiceFactory.class) + .createLifeCycleManagerStateful(new ApplicationContext(), getLCMProperties(controllerType)); + } catch (AppcClientException e) { + logger.error("Error in getting LifeCycleManagerStateful: {}",e.getMessage(), e); + // This null value will cause NullPointerException when used later. + // Error handling could certainly be improved here. + return null; + } + } + + public Status runCommand(Action action, org.onap.appc.client.lcm.model.ActionIdentifiers actionIdentifiers, + org.onap.appc.client.lcm.model.Payload payload, String requestID) + throws ApplicationControllerOrchestratorException { + Object requestObject; + requestObject = createRequest(action, actionIdentifiers, payload, requestID); + appCSupport.logLCMMessage(requestObject); + LifeCycleManagerStateful client = getAppCClient(); + Method lcmMethod = appCSupport.getAPIMethod(action.name(), client, false); + try { + Object response = lcmMethod.invoke(client, requestObject); + return appCSupport.getStatusFromGenericResponse(response); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException(String.format("%s : %s", "Unable to invoke action", action.toString()), e); + } + } + + protected Properties getLCMProperties() { + return getLCMProperties("appc"); + } + + protected Properties getLCMProperties(String controllerType) { + Properties properties = new Properties(); + + properties.put("topic.read", UrnPropertiesReader.getVariable("appc.client.topic.read.name")); + properties.put("topic.write", UrnPropertiesReader.getVariable("appc.client.topic.write")); + properties.put("SDNC-topic.read", UrnPropertiesReader.getVariable("appc.client.topic.sdnc.read")); + properties.put("SDNC-topic.write", UrnPropertiesReader.getVariable("appc.client.topic.sdnc.write")); + properties.put("topic.read.timeout", UrnPropertiesReader.getVariable("appc.client.topic.read.timeout")); + properties.put("client.response.timeout", UrnPropertiesReader.getVariable("appc.client.response.timeout")); + properties.put("poolMembers", UrnPropertiesReader.getVariable("appc.client.poolMembers")); + properties.put("controllerType", controllerType); + properties.put("client.key", UrnPropertiesReader.getVariable("appc.client.key")); + properties.put("client.secret", UrnPropertiesReader.getVariable("appc.client.secret")); + properties.put("client.name", CLIENT_NAME); + properties.put("service", UrnPropertiesReader.getVariable("appc.client.service")); + return properties; + } + + public Object createRequest(Action action, ActionIdentifiers identifier, Payload payload, String requestId) { + Object requestObject = appCSupport.getInput(action.name()); + try { + CommonHeader commonHeader = buildCommonHeader(requestId); + requestObject.getClass().getDeclaredMethod("setCommonHeader", CommonHeader.class).invoke(requestObject, + commonHeader); + requestObject.getClass().getDeclaredMethod("setAction", Action.class).invoke(requestObject, action); + requestObject.getClass().getDeclaredMethod("setActionIdentifiers", ActionIdentifiers.class) + .invoke(requestObject, identifier); + if (payload != null) { + requestObject.getClass().getDeclaredMethod("setPayload", Payload.class).invoke(requestObject, payload); + } + } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { + logger.error("Error building Appc request", e); + } + return requestObject; + } + + private CommonHeader buildCommonHeader(String requestId) { + CommonHeader commonHeader = new CommonHeader(); + commonHeader.setApiVer(API_VER); + commonHeader.setOriginatorId(ORIGINATOR_ID); + commonHeader.setRequestId(requestId == null ? UUID.randomUUID().toString() : requestId); + commonHeader.setSubRequestId(requestId); + Flags flags = new Flags(); + String flagsMode = "NORMAL"; + Mode mode = Mode.valueOf(flagsMode); + flags.setMode(mode); + String flagsForce = "FALSE"; + Force force = Force.valueOf(flagsForce); + flags.setForce(force); + flags.setTtl(FLAGS_TTL); + commonHeader.setFlags(flags); + Instant timestamp = Instant.now(); + ZULU zulu = new ZULU(timestamp.toString()); + commonHeader.setTimestamp(zulu); + return commonHeader; + } + + public Flags createRequestFlags() { + Flags flags = new Flags(); + flags.setTtl(6000); + return flags; + } +} diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerClientV2.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerClientV2.java new file mode 100644 index 0000000000..d4599a5248 --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerClientV2.java @@ -0,0 +1,154 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.appc; + +import org.onap.appc.client.lcm.api.AppcClientServiceFactoryProvider; +import org.onap.appc.client.lcm.api.AppcLifeCycleManagerServiceFactory; +import org.onap.appc.client.lcm.api.ApplicationContext; +import org.onap.appc.client.lcm.api.LifeCycleManagerStateful; +import org.onap.appc.client.lcm.exceptions.AppcClientException; +import org.onap.appc.client.lcm.model.*; +import org.onap.appc.client.lcm.model.Flags.Force; +import org.onap.appc.client.lcm.model.Flags.Mode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.time.Instant; +import java.util.Properties; +import java.util.UUID; + +@Component +@Deprecated +public class ApplicationControllerClientV2 { + + private static final String CLIENT_NAME = "MSO"; + private static final String API_VER = "2.00"; + private static final String ORIGINATOR_ID = "MSO"; + private static final int FLAGS_TTL = 65000; + private static Logger logger = LoggerFactory.getLogger(ApplicationControllerClientV2.class); + + //@Autowired + ApplicationControllerConfiguration applicationControllerConfiguration; + + //@Autowired + private ApplicationControllerSupport appCSupport; + + private static LifeCycleManagerStateful client; + + //@PostConstruct + public void buildClient() { + client = this.getAppCClient(""); + } + + //@PostConstruct + public void buildClient(String controllerType) { + client = this.getAppCClient(controllerType); + } + + public Status runCommand(Action action, ActionIdentifiers actionIdentifiers, Payload payload, String requestID) + throws ApplicationControllerOrchestratorException { + Object requestObject; + requestObject = createRequest(action, actionIdentifiers, payload, requestID); + appCSupport.logLCMMessage(requestObject); + Method lcmMethod = appCSupport.getAPIMethod(action.name(), client, false); + try { + Object response = lcmMethod.invoke(client, requestObject); + return appCSupport.getStatusFromGenericResponse(response); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException(String.format("%s : %s", "Unable to invoke action", action.toString()), e); + } + } + + public LifeCycleManagerStateful getAppCClient(String controllerType) { + if (client == null) + try { + client = AppcClientServiceFactoryProvider.getFactory(AppcLifeCycleManagerServiceFactory.class) + .createLifeCycleManagerStateful(new ApplicationContext(), getLCMProperties(controllerType)); + } catch (AppcClientException e) { + logger.error("Error in getting LifeCycleManagerStateful Client", e); + } + return client; + } + + protected Properties getLCMProperties(String controllerType) { + Properties properties = new Properties(); + properties.put("topic.read", applicationControllerConfiguration.getReadTopic()); + properties.put("topic.read.timeout", applicationControllerConfiguration.getReadTimeout()); + properties.put("client.response.timeout", applicationControllerConfiguration.getResponseTimeout()); + properties.put("topic.write", applicationControllerConfiguration.getWrite()); + properties.put("poolMembers", applicationControllerConfiguration.getPoolMembers()); + properties.put("client.key", applicationControllerConfiguration.getClientKey()); + properties.put("client.secret", applicationControllerConfiguration.getClientSecret()); + properties.put("client.name", CLIENT_NAME); + properties.put("service", applicationControllerConfiguration.getService()); + return properties; + } + + public Object createRequest(Action action, ActionIdentifiers identifier, Payload payload, String requestId) { + Object requestObject = appCSupport.getInput(action.name()); + try { + CommonHeader commonHeader = buildCommonHeader(requestId); + requestObject.getClass().getDeclaredMethod("setCommonHeader", CommonHeader.class).invoke(requestObject, + commonHeader); + requestObject.getClass().getDeclaredMethod("setAction", Action.class).invoke(requestObject, action); + requestObject.getClass().getDeclaredMethod("setActionIdentifiers", ActionIdentifiers.class) + .invoke(requestObject, identifier); + if (payload != null) { + requestObject.getClass().getDeclaredMethod("setPayload", Payload.class).invoke(requestObject, payload); + } + } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { + logger.error("Error building Appc request", e); + } + return requestObject; + } + + private CommonHeader buildCommonHeader(String requestId) { + CommonHeader commonHeader = new CommonHeader(); + commonHeader.setApiVer(API_VER); + commonHeader.setOriginatorId(ORIGINATOR_ID); + commonHeader.setRequestId(requestId == null ? UUID.randomUUID().toString() : requestId); + commonHeader.setSubRequestId(requestId); + Flags flags = new Flags(); + String flagsMode = "NORMAL"; + Mode mode = Mode.valueOf(flagsMode); + flags.setMode(mode); + String flagsForce = "FALSE"; + Force force = Force.valueOf(flagsForce); + flags.setForce(force); + flags.setTtl(FLAGS_TTL); + commonHeader.setFlags(flags); + Instant timestamp = Instant.now(); + ZULU zulu = new ZULU(timestamp.toString()); + commonHeader.setTimestamp(zulu); + return commonHeader; + } + + public Flags createRequestFlags() { + Flags flags = new Flags(); + flags.setTtl(6000); + return flags; + } +} diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerConfiguration.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerConfiguration.java new file mode 100644 index 0000000000..430767f24a --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerConfiguration.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 - 2018 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.appc; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Service; + +@Configuration +public class ApplicationControllerConfiguration { + @Value("${appc.client.topic.read.name}") + private String readTopic; + + @Value("${appc.client.topic.read.timeout}") + private String readTimeout; + + @Value("${appc.client.response.timeout}") + private String responseTimeout; + + @Value("${appc.client.topic.write}") + private String write; + + @Value("${appc.client.poolMembers}") + private String poolMembers; + + @Value("${appc.client.key}") + private String clientKey; + + @Value("${appc.client.secret}") + private String clientSecret; + + @Value("${appc.client.service}") + private String service; + + public String getClientKey() { + return clientKey; + } + + public String getClientSecret() { + return clientSecret; + } + + public String getPoolMembers() { + return poolMembers; + } + + public String getReadTimeout() { + return readTimeout; + } + + public String getResponseTimeout() { + return responseTimeout; + } + + public String getReadTopic() { + return readTopic; + } + + public String getService() { + return service; + } + + public String getWrite() { + return write; + } +} + diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerOrchestrator.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerOrchestrator.java new file mode 100644 index 0000000000..84e0f93294 --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerOrchestrator.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.appc; + +import java.util.Optional; + +import org.onap.so.client.appc.ApplicationControllerSupport.StatusCategory; + +import org.onap.appc.client.lcm.model.Action; +import org.onap.appc.client.lcm.model.ActionIdentifiers; +import org.onap.appc.client.lcm.model.Payload; +import org.onap.appc.client.lcm.model.Status; + +public class ApplicationControllerOrchestrator { + + public Status vnfCommand(Action action, String requestId, String vnfId, Optional<String> vserverId, Optional<String> request, String controllerType) throws ApplicationControllerOrchestratorException { + ApplicationControllerClient client = new ApplicationControllerClient(controllerType); + Status status; + ActionIdentifiers actionIdentifiers = new ActionIdentifiers(); + actionIdentifiers.setVnfId(vnfId); + if (vserverId.isPresent()) { + actionIdentifiers.setVserverId(vserverId.get()); + } + Payload payload = null; + if (request.isPresent()) { + payload = new Payload(request.get()); + } + status = client.runCommand(action, actionIdentifiers, payload, requestId); + if (ApplicationControllerSupport.getCategoryOf(status).equals(StatusCategory.ERROR)) { + throw new ApplicationControllerOrchestratorException(status.getMessage(), status.getCode()); + } else { + return status; + } + } +} diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerOrchestratorException.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerOrchestratorException.java new file mode 100644 index 0000000000..2532e485ed --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerOrchestratorException.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.appc; + +public class ApplicationControllerOrchestratorException extends Exception { + + private final int appcCode; + + public ApplicationControllerOrchestratorException(String message, int code) { + super(message); + appcCode = code; + } + + public int getAppcCode() + { + return appcCode; + } +} diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerSupport.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerSupport.java new file mode 100644 index 0000000000..ef8749ece9 --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/appc/ApplicationControllerSupport.java @@ -0,0 +1,215 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.appc; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.springframework.stereotype.Component; + +import org.onap.appc.client.lcm.api.LifeCycleManagerStateful; +import org.onap.appc.client.lcm.api.ResponseHandler; +import org.onap.appc.client.lcm.model.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import org.springframework.stereotype.Service; + +public class ApplicationControllerSupport { + + private static final int ACCEPT_SERIES = 100; + private static final int ERROR_SERIES = 200; + private static final int REJECT_SERIES = 300; + private static final int SUCCESS_SERIES = 400; + private static final int SUCCESS_STATUS = SUCCESS_SERIES; + private static final int PARTIAL_SERIES = 500; + private static final int PARTIAL_SUCCESS_STATUS = PARTIAL_SERIES; + private static final int PARTIAL_FAILURE_STATUS = PARTIAL_SERIES + 1; + + private static Logger logger = LoggerFactory.getLogger(ApplicationControllerSupport.class); + private String lcmModelPackage = "org.onap.appc.client.lcm.model"; + + /** + * @param action + * @return + * @throws ClassNotFoundException + * @throws InstantiationException + * @throws IllegalAccessException + */ + public Object getInput(String action) { + try { + return getInputClass(action).newInstance(); + } catch (IllegalAccessException | InstantiationException e) { + throw new RuntimeException( + String.format("%s : %s", "Unable to instantiate viable LCM Kit input class for action", action), e); + } + } + + /** + * @param action + * @return + * @throws ClassNotFoundException + */ + public Method getAPIMethod(String action, LifeCycleManagerStateful lcmStateful, boolean async) { + Method[] methods = lcmStateful.getClass().getMethods(); + for (Method method : methods) { + if (method.getName().equalsIgnoreCase(action)) { + Class<?>[] methodParameterTypes = method.getParameterTypes(); + if (methodParameterTypes.length > 0) { + if (getInputClass(action).equals(methodParameterTypes[0])) { + if (async) { + if (methodParameterTypes.length == 2 + && ResponseHandler.class.isAssignableFrom(methodParameterTypes[1])) { + return method; + } + } else if (methodParameterTypes.length == 1) { + return method; + } + } + } + } + } + throw new RuntimeException(String.format("%s : %s, async=%b", + "Unable to derive viable LCM Kit API method for action", action, async)); + } + + public Status getStatusFromGenericResponse(Object response) { + Method statusReader = getBeanPropertyMethodFor(response.getClass(), "status", false); + if (statusReader != null) { + try { + return (Status) statusReader.invoke(response); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + logger.error("Unable to obtain status from LCM Kit response", e); + } + } + return new Status(); + } + + public static StatusCategory getCategoryOf(Status status) { + int codeSeries = status.getCode() - (status.getCode() % 100); + switch (codeSeries) { + case ACCEPT_SERIES: + return StatusCategory.NORMAL; + case ERROR_SERIES: + case REJECT_SERIES: + return StatusCategory.ERROR; + case SUCCESS_SERIES: + return status.getCode() == SUCCESS_STATUS ? StatusCategory.NORMAL : StatusCategory.ERROR; + case PARTIAL_SERIES: + switch (status.getCode()) { + case PARTIAL_SUCCESS_STATUS: + return StatusCategory.NORMAL; + case PARTIAL_FAILURE_STATUS: + return StatusCategory.ERROR; + default: + return StatusCategory.WARNING; + } + default: + return StatusCategory.WARNING; + } + } + + public static boolean getFinalityOf(Status status) { + int codeSeries = status.getCode() - (status.getCode() % 100); + switch (codeSeries) { + case ACCEPT_SERIES: + case PARTIAL_SERIES: + return false; + case ERROR_SERIES: + case REJECT_SERIES: + case SUCCESS_SERIES: + return true; + default: + return true; + } + } + + private Method getBeanPropertyMethodFor(Class<?> clazz, String propertyName, boolean isWriter) { + BeanInfo beanInfo; + try { + beanInfo = Introspector.getBeanInfo(clazz, Object.class); + } catch (IntrospectionException e) { + throw new RuntimeException( + String.format("Unable to produce bean property method for class : %s, property : %s, writer=%b", + clazz.getName(), propertyName, isWriter), + e); + } + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + if (propertyDescriptor.getName().equals(propertyName)) { + return isWriter ? propertyDescriptor.getWriteMethod() : propertyDescriptor.getReadMethod(); + } + } + throw new RuntimeException( + String.format("Unable to produce bean property method for class : %s, property : %s, writer=%b", + clazz.getName(), propertyName, isWriter)); + } + + /** + * @param action + * @return + * @throws ClassNotFoundException + */ + private Class<?> getInputClass(String action) { + try { + return Class.forName(lcmModelPackage + '.' + action + "Input"); + } catch (ClassNotFoundException e) { + throw new RuntimeException(String.format("%s : %s using package : %s", + "Unable to identify viable LCM Kit input class for action", action, lcmModelPackage), e); + } + } + + public enum StatusCategory { + NORMAL("normal"), WARNING("warning"), ERROR("error"); + + private final String category; + + private StatusCategory(final String category) { + this.category = category; + } + + @Override + public String toString() { + return category; + } + } + + public void logLCMMessage(Object message) { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setSerializationInclusion(Include.NON_NULL); + ObjectWriter writer = objectMapper.writerWithDefaultPrettyPrinter(); + String inputAsJSON; + try { + inputAsJSON = writer.writeValueAsString(message); + logger.info("LCM Kit input message follows: {}" , inputAsJSON); + } catch (JsonProcessingException e) { + logger.error("Error in logging LCM Message", e); + } + } +} |