aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRamaPrasad Amaranarayana (ra5425) <ra5425@att.com>2018-09-19 18:41:45 -0400
committerRamaPrasad Amaranarayana (ra5425) <ra5425@att.com>2018-09-19 18:41:45 -0400
commitaa45355f7b4ec0b37e6a5540617f3b54f4efb389 (patch)
treeca01a90100b87daeac90bea4a36a02967feb33f5
parent93c1a756bc483c4dae1350820a78cb72d052f2cf (diff)
Change Management Schedule Optimization
Adding CMSO Service Code for Change Management Schedule Optimization Change-Id: I502ee905e9197fbb015e36b4181f8aaa2d3eb555 Issue-ID: OPTFRA-353 Signed-off-by: RamaPrasad Amaranarayana (ra5425) <ra5425@att.com>
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOClientFilters.java75
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOContainerFilters.java128
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/filters/MessageHeaders.java105
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/so/bean/MsoOrchestrationQueryResponse.java76
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusClient.java289
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusJob.java92
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/sostatus/ScheduleStatusJob.java198
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmClient.java539
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmEndpoints.java134
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmStatusClient.java317
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/BuildCreateRequest.java202
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmApprovalStatusEnum.java47
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmAsset.java44
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmChangeInfo.java144
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmStatusEnum.java36
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfChangeManagementResponse.java52
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfCmResponse200.java54
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoRequestReferences.java54
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoResponse.java44
-rw-r--r--cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfVidCmResponse.java72
20 files changed, 2702 insertions, 0 deletions
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOClientFilters.java b/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOClientFilters.java
new file mode 100644
index 0000000..6396dca
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOClientFilters.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.filters;
+
+import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
+import java.io.IOException;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.core.MultivaluedMap;
+import org.onap.optf.cmso.filters.MessageHeaders.HeadersEnum;
+import org.onap.optf.cmso.service.rs.CMSOServiceImpl;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+// @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
+@Component
+public class CMSOClientFilters implements ClientRequestFilter, ClientResponseFilter {
+
+ private static EELFLogger log = EELFManager.getInstance().getLogger(CMSOServiceImpl.class);
+ private static String appId = "cmso";
+
+ @Override
+ public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+ // On the way back
+ log.info("SchedulerClientFilters.filter(r,r)");
+ }
+
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ // On the way out
+ log.info("SchedulerClientFilters.filter(r)" + requestContext.getUri().getPath());
+ MultivaluedMap<String, Object> headers = requestContext.getHeaders();
+
+ String transactionId = (String) headers.getFirst(MessageHeaders.HeadersEnum.TransactionID.toString());
+ String mdcId = MDC.get(MDC_KEY_REQUEST_ID);
+ if (transactionId == null || transactionId.equals(""))
+ if (mdcId != null)
+ headers.add(HeadersEnum.TransactionID.toString(), mdcId);
+ headers.add(HeadersEnum.FromAppID.toString(), appId);
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOContainerFilters.java b/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOContainerFilters.java
new file mode 100644
index 0000000..784ab5a
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOContainerFilters.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.filters;
+
+import java.io.IOException;
+import java.util.UUID;
+import javax.annotation.Priority;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.ext.Provider;
+import org.onap.optf.cmso.common.LogMessages;
+import org.onap.optf.cmso.filters.MessageHeaders.HeadersEnum;
+import org.onap.optf.cmso.service.rs.CMSOServiceImpl;
+import org.springframework.stereotype.Component;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+@Priority(1)
+@Provider
+@Component
+public class CMSOContainerFilters implements ContainerRequestFilter, ContainerResponseFilter {
+ private static EELFLogger log = EELFManager.getInstance().getLogger(CMSOServiceImpl.class);
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
+ throws IOException {
+ try {
+ log.info("SchedulerContainerFilters.filter(r,r)");
+ MultivaluedMap<String, String> reqHeaders = requestContext.getHeaders();
+ MultivaluedMap<String, Object> respHeaders = responseContext.getHeaders();
+ String minorVersion = (String) reqHeaders.getFirst(HeadersEnum.MinorVersion.toString());
+ respHeaders.add(HeadersEnum.MinorVersion.toString(), minorVersion);
+ respHeaders.add(HeadersEnum.LatestVersion.toString(), MessageHeaders.latestVersion);
+ respHeaders.add(HeadersEnum.PatchVersion.toString(), MessageHeaders.patchVersion);
+
+ } catch (Exception e) {
+ if (e instanceof WebApplicationException) {
+ log.info(LogMessages.EXPECTED_EXCEPTION, e.getMessage());
+ } else {
+ log.info(LogMessages.UNEXPECTED_EXCEPTION, e.getMessage());
+ }
+ }
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+ try {
+ // On the way in
+ log.info("SchedulerContainerFilters.filter(r) path={} ", requestContext.getUriInfo().getPath().toString());
+
+ String majorVersion = requestContext.getUriInfo().getPath();
+ if (majorVersion != null) {
+
+ if (majorVersion.startsWith("dispatch/"))
+ return;
+ majorVersion = majorVersion.replaceAll("/.*$", "");
+ }
+ if (!MessageHeaders.validateMajorVersion(majorVersion)) {
+ ResponseBuilder builder = null;
+ String response = "Unsupported Major version";
+ builder = Response.status(Response.Status.NOT_FOUND).entity(response);
+ throw new WebApplicationException(builder.build());
+ }
+ MultivaluedMap<String, String> headers = requestContext.getHeaders();
+ String transactionId = (String) headers.getFirst(HeadersEnum.TransactionID.toString());
+ if (transactionId == null) {
+ transactionId = UUID.randomUUID().toString();
+ headers.add(HeadersEnum.TransactionID.toString(), transactionId);
+ }
+ String minorVersion = (String) headers.getFirst(HeadersEnum.MinorVersion.toString());
+ if (minorVersion == null) {
+ minorVersion = MessageHeaders.supportedMajorVersions.get(majorVersion);
+ headers.add(HeadersEnum.MinorVersion.toString(), minorVersion);
+ }
+ if (!MessageHeaders.validateMajorMinorVersion(majorVersion, minorVersion)) {
+ ResponseBuilder builder = null;
+ String response = "Unsupported API version";
+ builder = Response.status(Response.Status.NOT_FOUND).entity(response);
+ throw new WebApplicationException(builder.build());
+
+ }
+ } catch (Exception e) {
+ if (e instanceof WebApplicationException) {
+ log.info(LogMessages.EXPECTED_EXCEPTION, e.getMessage());
+ throw e;
+ } else {
+ log.info(LogMessages.UNEXPECTED_EXCEPTION, e.getMessage());
+ }
+ }
+
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/filters/MessageHeaders.java b/cmso-service/src/main/java/org/onap/optf/cmso/filters/MessageHeaders.java
new file mode 100644
index 0000000..ba3efa3
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/filters/MessageHeaders.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.filters;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class MessageHeaders {
+ public enum HeadersEnum {
+ UNDEFINED("UNDEFINED"), TransactionID("X-TransactionId"), FromAppID("X-FromAppId"), MinorVersion(
+ "X-MinorVersion"), PatchVersion("X-PatchVersion"), LatestVersion("X-LatestVersion"),;
+
+ private final String text;
+ private final ArrayList<String> list;
+
+ private HeadersEnum(String text) {
+ this.text = text;
+ this.list = new ArrayList<>();
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+ }
+
+ public static final Map<String, String> supportedMajorVersions = new HashMap<String, String>();
+ static {
+ supportedMajorVersions.put("v1", "0");
+ supportedMajorVersions.put("v2", "0");
+ }
+ public static final Set<String> supportedMajorMinorVersions = new HashSet<String>();
+ static {
+ supportedMajorMinorVersions.add("v1.0");
+ supportedMajorMinorVersions.add("v2.0");
+ }
+ public static final String latestVersion = "2.0.0";
+ public static final String patchVersion = "0";
+
+ public static HeadersEnum fromString(String text) {
+ for (HeadersEnum e : HeadersEnum.values())
+ if (e.text.equals(text))
+ return e;
+ return HeadersEnum.UNDEFINED;
+ }
+
+ public static String getPatchVersion() {
+ return patchVersion;
+ }
+
+ public static String getLatestVersion() {
+ return latestVersion;
+ }
+
+ public static boolean validateMajorVersion(String major) {
+ String majorKey = major.toLowerCase();
+ if (!supportedMajorVersions.containsKey(majorKey))
+ return false;
+ return true;
+ }
+
+ public static boolean validateMajorMinorVersion(String major, String minor) {
+ String majorKey = major.toLowerCase();
+ if (!supportedMajorVersions.containsKey(majorKey))
+ return false;
+
+ if (minor != null) {
+ String majorMinorKey = majorKey + "." + minor;
+ return supportedMajorMinorVersions.contains(majorMinorKey);
+ }
+ return true;
+ }
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/so/bean/MsoOrchestrationQueryResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/so/bean/MsoOrchestrationQueryResponse.java
new file mode 100644
index 0000000..2e46be0
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/so/bean/MsoOrchestrationQueryResponse.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.so.bean;
+
+public class MsoOrchestrationQueryResponse {
+ public enum MSO_STATUS {
+ UNKNOWN, COMPLETE, FAILED, IN_PROGRESS,
+ }
+
+ String requestState;
+ String statusMessage;
+ Integer percentProgress;
+ String finishTime;
+
+ public String getRequestState() {
+ return requestState;
+ }
+
+ public void setRequestState(String requestState) {
+ this.requestState = requestState;
+ }
+
+ public String getStatusMessage() {
+ return statusMessage;
+ }
+
+ public void setStatusMessage(String statusMessage) {
+ this.statusMessage = statusMessage;
+ }
+
+ public Integer getPercentProgress() {
+ return percentProgress;
+ }
+
+ public void setPercentProgress(Integer percentProgress) {
+ this.percentProgress = percentProgress;
+ }
+
+ public String getFinishTime() {
+ return finishTime;
+ }
+
+ public void setFinishTime(String finishTime) {
+ this.finishTime = finishTime;
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusClient.java b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusClient.java
new file mode 100644
index 0000000..42f282a
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusClient.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.sostatus;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.onap.optf.cmso.common.BasicAuthenticatorFilter;
+import org.onap.optf.cmso.common.CMSStatusEnum;
+import org.onap.optf.cmso.common.LogMessages;
+import org.onap.optf.cmso.common.Mdc;
+import org.onap.optf.cmso.common.PropertiesManagement;
+import org.onap.optf.cmso.filters.CMSOClientFilters;
+import org.onap.optf.cmso.model.ChangeManagementSchedule;
+import org.onap.optf.cmso.model.dao.ChangeManagementGroupDAO;
+import org.onap.optf.cmso.model.dao.ChangeManagementScheduleDAO;
+import org.onap.optf.cmso.model.dao.ScheduleDAO;
+import org.onap.optf.cmso.service.rs.models.HealthCheckComponent;
+import org.onap.optf.cmso.so.bean.MsoOrchestrationQueryResponse;
+import org.onap.optf.cmso.so.bean.MsoOrchestrationQueryResponse.MSO_STATUS;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+@Component
+public class MsoStatusClient {
+ private static EELFLogger log = EELFManager.getInstance().getLogger(MsoStatusClient.class);
+ private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();
+ private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();
+ private static EELFLogger metrics = EELFManager.getInstance().getMetricsLogger();
+
+ @Autowired
+ ChangeManagementScheduleDAO cmScheduleDAO;
+
+ @Autowired
+ ChangeManagementGroupDAO cmGroupDAO;
+
+ @Autowired
+ ScheduleDAO scheduleDAO;
+
+ @Autowired
+ Environment env;
+
+ @Autowired
+ PropertiesManagement pm;
+
+ public void execute(Integer id) throws JobExecutionException {
+ debug.debug(LogMessages.MSO_STATUS_JOB, "Entered", id.toString());
+ try {
+ ChangeManagementSchedule cmSchedule = cmScheduleDAO.lockOne(id);
+ if (cmSchedule == null) {
+ log.warn(LogMessages.MSO_POLLING_MISSING_SCHEDULE, id.toString());
+ return;
+ }
+ poll(cmSchedule);
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ debug.debug(LogMessages.MSO_STATUS_JOB, "Exited", id.toString());
+ }
+
+ @Transactional
+ public void poll(ChangeManagementSchedule cmSchedule) {
+ Map<String, String> mdcSave = Mdc.save();
+ try {
+ // Re-fetch schedule inside transaction??
+ String requestId = cmSchedule.getMsoRequestId();
+ String url = env.getProperty("so.url");
+ String user = env.getProperty("so.user");
+ String pass = pm.getProperty("so.pass", "");
+ if (!url.endsWith("/"))
+ url = url + "/";
+ url = url + requestId;
+ Client client = ClientBuilder.newClient();
+ client.register(new BasicAuthenticatorFilter(user, pass));
+ client.register(new CMSOClientFilters());
+ WebTarget target = client.target(url);
+ Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON);
+ Response response = null;
+ cmSchedule.setMsoTimeMillis(System.currentTimeMillis());
+ Mdc.metricStart(requestId, url);
+ response = invocationBuilder.get();
+ Mdc.metricEnd(response);
+ metrics.info(LogMessages.SO_API, requestId);
+ switch (response.getStatus()) {
+ case 200: {
+ String respString = response.readEntity(String.class);
+ debug.debug("MSO response {}", respString);
+ MsoOrchestrationQueryResponse resp = getResponseStatus(respString);
+ if (resp != null) {
+ cmSchedule.setMsoStatus(resp.getRequestState());
+ cmSchedule.setMsoMessage(resp.getStatusMessage());
+ MSO_STATUS msoStatus = MSO_STATUS.UNKNOWN;
+ try {
+ msoStatus = MSO_STATUS.valueOf(resp.getRequestState());
+ } catch (Exception e) {
+ errors.error("Unregcognized status from MSO: " + resp.getRequestState());
+ }
+ long finishTime = getFinishTime(resp);
+ switch (msoStatus) {
+ case COMPLETE:
+ cmSchedule.setExecutionCompletedTimeMillis(finishTime);
+ cmSchedule.setStatus(CMSStatusEnum.Completed.toString());
+ break;
+ case FAILED:
+ cmSchedule.setExecutionCompletedTimeMillis(finishTime);
+ cmSchedule.setStatus(CMSStatusEnum.Failed.toString());
+ break;
+ case UNKNOWN:
+ default:
+ }
+ } else {
+ // Do not keep polling...
+ cmSchedule.setStatus(CMSStatusEnum.Error.toString());
+ cmSchedule.setMsoStatus("Bad Response");
+ cmSchedule.setMsoMessage("Unable to parse :" + respString);
+
+ }
+
+ }
+ break;
+ case 404: // Not found
+ {
+ // Do not keep polling...
+ cmSchedule.setStatus(CMSStatusEnum.Failed.toString());
+ cmSchedule.setMsoStatus("Not found");
+ cmSchedule.setMsoMessage("Call to MSO Failed :" + response.toString());
+ }
+ break;
+ case 400: // Bad request
+ {
+ // Do not keep polling...
+ cmSchedule.setStatus(CMSStatusEnum.Error.toString());
+ cmSchedule.setMsoStatus("Bad Request");
+ cmSchedule.setMsoMessage("Call to MSO Failed :" + response.toString());
+ }
+ break;
+ case 500:
+ default: {
+ cmSchedule.setStatus(CMSStatusEnum.Error.toString());
+ cmSchedule.setMsoStatus("Failed");
+ cmSchedule.setMsoMessage("Call to MSO Failed :" + response.toString());
+ }
+ }
+ } catch (ProcessingException e) {
+ debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ // Probably a transient error... Keep polling
+ cmSchedule.setMsoTimeMillis(System.currentTimeMillis());
+ cmSchedule.setMsoStatus("ConnectionException");
+ cmSchedule.setMsoMessage("Could not call MSO:" + e.getMessage());
+ } catch (Exception e) {
+ debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ // Probably a transient error... Keep polling
+ cmSchedule.setMsoTimeMillis(System.currentTimeMillis());
+ cmSchedule.setMsoStatus("Exception");
+ cmSchedule.setMsoMessage("Could not call MSO:" + e.getMessage());
+ } finally {
+ Mdc.restore(mdcSave);
+ }
+ // Propagate final MSO status to top level
+ cmScheduleDAO.save(cmSchedule);
+ propagateStatus(cmSchedule);
+
+ }
+
+ private long getFinishTime(MsoOrchestrationQueryResponse resp) {
+ // Just in case we cannot parse the time returned by MSO as a UTC time.
+ long finishTime = System.currentTimeMillis();
+ String timestr = resp.getFinishTime();
+ if (timestr != null) {
+ try {
+ Date dateTime = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z").parse(timestr);
+ finishTime = dateTime.getTime();
+ } catch (Exception e) {
+ debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, "Unable to parse MSO fisnish timestamp: " + timestr);
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, "Unable to parse MSO fisnish timestamp: " + timestr);
+ }
+ }
+ return finishTime;
+ }
+
+ private void propagateStatus(ChangeManagementSchedule cmSchedule) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private MsoOrchestrationQueryResponse getResponseStatus(String resp) {
+ try {
+ ObjectMapper om = new ObjectMapper();
+ ObjectNode json = (ObjectNode) om.readTree(resp);
+ ObjectNode request = (ObjectNode) json.get("request");
+ ObjectNode requestStatus = (ObjectNode) request.get("requestStatus");
+ MsoOrchestrationQueryResponse msoResponse =
+ om.treeToValue(requestStatus, MsoOrchestrationQueryResponse.class);
+ return msoResponse;
+ } catch (Exception e) {
+ log.warn("Exception parsing MSO response", e);
+ log.warn("MSO response:\n" + resp);
+ }
+ return null;
+ }
+
+ public HealthCheckComponent healthCheck() {
+ Map<String, String> mdcSave = Mdc.save();
+ String requestId = "healthCheck";
+ String url = env.getProperty("so.url");
+ String user = env.getProperty("so.user");
+ String pass = pm.getProperty("so.pass", "");
+ if (!url.endsWith("/"))
+ url = url + "/";
+ url = url + "healthcheck";
+
+ HealthCheckComponent hcc = new HealthCheckComponent();
+ hcc.setName("MSO Interface");
+ hcc.setUrl(url);
+
+ Client client = ClientBuilder.newClient();
+ client.register(new BasicAuthenticatorFilter(user, pass));
+ WebTarget target = client.target(url);
+ Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON);
+ Response response = null;
+ try {
+ Mdc.metricStart(requestId, url);
+ response = invocationBuilder.get();
+ Mdc.metricEnd(response);
+ metrics.info(LogMessages.SO_API, requestId);
+ switch (response.getStatus()) {
+ case 200:
+ case 204:
+ hcc.setHealthy(true);
+ hcc.setStatus("OK");
+ break;
+ default: {
+ String respString = response.readEntity(String.class);
+ hcc.setStatus(respString);
+ }
+ }
+ } catch (Exception e) {
+ hcc.setStatus(e.getMessage());
+ } finally {
+ Mdc.restore(mdcSave);
+ }
+ return hcc;
+ }
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusJob.java b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusJob.java
new file mode 100644
index 0000000..29853d1
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusJob.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.sostatus;
+
+import org.onap.optf.cmso.common.LogMessages;
+import org.onap.optf.cmso.common.Mdc;
+import org.onap.optf.cmso.model.ChangeManagementSchedule;
+import org.onap.optf.cmso.model.dao.ChangeManagementScheduleDAO;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+/**
+ * This is the Quartz Job that is run to send the workflow to VID for execution
+ *
+ *
+ */
+@Component
+@DisallowConcurrentExecution
+public class MsoStatusJob implements Job {
+ private static EELFLogger log = EELFManager.getInstance().getLogger(MsoStatusJob.class);
+ private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();
+ private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();
+
+ @Autowired
+ MsoStatusClient mso;
+
+ @Autowired
+ ChangeManagementScheduleDAO cmScheduleDAO;
+
+ @Autowired
+ Environment env;
+
+ public enum ContextKeys {
+ msoRequestId, scheduleId,
+ }
+
+ @Override
+ public void execute(JobExecutionContext context) throws JobExecutionException {
+ Mdc.quartzJobBegin(context);
+ Integer id = context.getJobDetail().getJobDataMap().getInt(ContextKeys.scheduleId.toString());
+ String requestId = context.getJobDetail().getJobDataMap().getString(ContextKeys.msoRequestId.toString());
+ debug.debug(LogMessages.MSO_STATUS_JOB, "Entered", requestId, id.toString());
+ try {
+ ChangeManagementSchedule cmSchedule = cmScheduleDAO.findById(id).orElse(null);
+ if (cmSchedule == null) {
+ log.warn(LogMessages.MSO_POLLING_MISSING_SCHEDULE, id.toString(), requestId);
+ return;
+ }
+ mso.poll(cmSchedule);
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ debug.debug(LogMessages.MSO_STATUS_JOB, "Exited", requestId, id.toString());
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/ScheduleStatusJob.java b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/ScheduleStatusJob.java
new file mode 100644
index 0000000..cd74bc4
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/ScheduleStatusJob.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.sostatus;
+
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.onap.optf.cmso.common.BasicAuthenticatorFilter;
+import org.onap.optf.cmso.common.DomainsEnum;
+import org.onap.optf.cmso.common.LogMessages;
+import org.onap.optf.cmso.common.Mdc;
+import org.onap.optf.cmso.common.PropertiesManagement;
+import org.onap.optf.cmso.model.ChangeManagementSchedule;
+import org.onap.optf.cmso.model.Schedule;
+import org.onap.optf.cmso.model.dao.ChangeManagementScheduleDAO;
+import org.onap.optf.cmso.model.dao.ScheduleDAO;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.SchedulerException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+/**
+ * This is the Quartz Job that is run to send the workflow to VID for execution
+ *
+ *
+ */
+@Component
+@DisallowConcurrentExecution
+public class ScheduleStatusJob implements Job {
+ private static EELFLogger log = EELFManager.getInstance().getLogger(ScheduleStatusJob.class);
+ private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();
+ private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();
+ private static EELFLogger metrics = EELFManager.getInstance().getMetricsLogger();
+
+ @Autowired
+ ScheduleDAO scheduleDAO;
+
+ @Autowired
+ ChangeManagementScheduleDAO cmScheduleDAO;
+
+ @Autowired
+ PropertiesManagement pm;
+
+ @Autowired
+ Environment env;
+
+ @Override
+ public void execute(JobExecutionContext context) throws JobExecutionException {
+ debug.debug(LogMessages.SCHEDULE_STATUS_JOB, "Entered");
+ try {
+ // First poll SO for WF status
+ List<ChangeManagementSchedule> list = cmScheduleDAO.findAllTriggered();
+ for (ChangeManagementSchedule s : list) {
+ debug.debug("Dispathcing to check status of CM schedule Id=" + s.getId());
+ dispatchMso(s.getId());
+ }
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ try {
+
+ //
+ // Update overall status of in flight schedules including closing tickets
+ List<Schedule> list = scheduleDAO.findAllInProgress(DomainsEnum.ChangeManagement.toString());
+ for (Schedule s : list) {
+ debug.debug("Dispatching to check status of scheduleId=" + s.getScheduleId());
+ dispatchScheduleStatusChecker(s.getId());
+ }
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ debug.debug(LogMessages.SCHEDULE_STATUS_JOB, "Exited");
+ }
+
+ public void dispatchScheduleStatusChecker(Integer id) {
+ Map<String, String> mdcSave = Mdc.save();
+ try {
+ String url = env.getProperty("cmso.dispatch.url", "http://localhost:8089");
+ String path = env.getProperty("cmso.dispatch.status.path", "/cmso/dispatch/schedulestatus/");
+ url = url + path + id;
+ String user = env.getProperty("mechid.user", "");
+ String pass = pm.getProperty("mechid.pass", "");
+ Client client = ClientBuilder.newClient();
+ client.register(new BasicAuthenticatorFilter(user, pass));
+ WebTarget target = client.target(url);
+ Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON);
+ Response response = null;
+ try {
+ Mdc.metricStart(id.toString(), url);
+ response = invocationBuilder.get();
+ Mdc.metricEnd(response);
+ metrics.info(LogMessages.SCHEDULE_STATUS_JOB, id.toString());
+ switch (response.getStatus()) {
+ case 200:
+ log.info("Returned from dispatch call");
+ break;
+ case 400: // Bad request
+ default: {
+
+ throw new SchedulerException(
+ "Invalid return from dispach service: " + url + " : " + response.toString());
+ }
+ }
+ } catch (Exception e) {
+ debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ } catch (Exception e) {
+ debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ } finally {
+ Mdc.restore(mdcSave);
+ }
+
+ }
+
+ public void dispatchMso(Integer id) {
+ Map<String, String> mdcSave = Mdc.save();
+ try {
+ String url = env.getProperty("cmso.dispatch.url", "http://localhost:8089");
+ String path = env.getProperty("cmso.dispatch.sostatus.path", "/cmso/dispatch/sostatus/");
+ url = url + path + id;
+ String user = env.getProperty("mechid.user", "");
+ String pass = pm.getProperty("mechid.pass", "");
+ Client client = ClientBuilder.newClient();
+ client.register(new BasicAuthenticatorFilter(user, pass));
+ WebTarget target = client.target(url);
+ Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON);
+ Response response = null;
+ try {
+ Mdc.metricStart(id.toString(), url);
+ response = invocationBuilder.get();
+ Mdc.metricEnd(response);
+ metrics.info(LogMessages.SCHEDULE_STATUS_JOB, id.toString());
+ switch (response.getStatus()) {
+ case 200:
+ log.info("Returned from dispatch call");
+ break;
+ case 400: // Bad request
+ default: {
+
+ throw new SchedulerException(
+ "Invalid return from dispach service: " + url + " : " + response.toString());
+ }
+ }
+ } catch (Exception e) {
+ debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ } catch (Exception e) {
+ debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ } finally {
+ Mdc.restore(mdcSave);
+ }
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmClient.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmClient.java
new file mode 100644
index 0000000..b8aed57
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmClient.java
@@ -0,0 +1,539 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.ticketmgt;
+
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import org.apache.commons.lang3.text.StrSubstitutor;
+import org.joda.time.format.ISODateTimeFormat;
+import org.onap.optf.cmso.common.BasicAuthenticatorFilter;
+import org.onap.optf.cmso.common.CmHelpers;
+import org.onap.optf.cmso.common.LogMessages;
+import org.onap.optf.cmso.common.Mdc;
+import org.onap.optf.cmso.common.PropertiesManagement;
+import org.onap.optf.cmso.common.exceptions.CMSException;
+import org.onap.optf.cmso.filters.CMSOClientFilters;
+import org.onap.optf.cmso.model.ChangeManagementGroup;
+import org.onap.optf.cmso.model.ChangeManagementSchedule;
+import org.onap.optf.cmso.model.DomainData;
+import org.onap.optf.cmso.model.Schedule;
+import org.onap.optf.cmso.model.dao.ChangeManagementScheduleDAO;
+import org.onap.optf.cmso.service.rs.models.CmDomainDataEnum;
+import org.onap.optf.cmso.service.rs.models.HealthCheckComponent;
+import org.onap.optf.cmso.ticketmgt.TmEndpoints.Endpoint;
+import org.onap.optf.cmso.ticketmgt.TmStatusClient.ClosureCode;
+import org.onap.optf.cmso.ticketmgt.bean.BuildCreateRequest;
+import org.onap.optf.cmso.ticketmgt.bean.BuildCreateRequest.Variables;
+import org.onap.optf.cmso.ticketmgt.bean.TmAsset;
+import org.onap.optf.cmso.ticketmgt.bean.TmChangeInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+@Component
+public class TmClient {
+ private static EELFLogger log = EELFManager.getInstance().getLogger(TmClient.class);
+ private static EELFLogger metrics = EELFManager.getInstance().getMetricsLogger();
+ private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();
+ private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();
+
+ @Autowired
+ Environment env;
+
+ @Autowired
+ PropertiesManagement pm;
+
+ @Autowired
+ ChangeManagementScheduleDAO cmScheduleDAO;
+
+ @Autowired
+ BuildCreateRequest buildCreateRequest;
+
+ @Autowired
+ TmEndpoints tmEndpoints;
+
+ public String createChangeTicket(Schedule schedule, ChangeManagementGroup group, List<String> vnfNames,
+ List<DomainData> domainData) throws CMSException {
+
+ String changeId = "";
+ String workflowName = CmHelpers.getDomainData(domainData, CmDomainDataEnum.WorkflowName);
+ Map<String, Object> variables = getVariables(schedule, group, vnfNames, domainData);
+ List<TmAsset> assetList = getAssetList(vnfNames);
+ JsonNode createChangeRecord = buildCreateRequest.createChangeRecordRequest(variables, assetList, workflowName);
+ debug.debug("createChangeRecord=" + createChangeRecord.toString());
+ changeId = postCreateChangeTicket(createChangeRecord, schedule.getScheduleId());
+ return changeId;
+ }
+
+ public void closeTicket(Schedule schedule, ChangeManagementGroup group, List<ChangeManagementSchedule> cmSchedules,
+ String changeId, ClosureCode closureCode, String closingComments) throws CMSException {
+ Map<String, Object> variables =
+ getCloseVariables(schedule, group, cmSchedules, changeId, closureCode, closingComments);
+ JsonNode closeChangeRecord = buildCreateRequest.createCloseCancelChangeRecord(variables);
+ debug.debug("closeChangeRecord=" + closeChangeRecord.toString());
+ postCloseChangeTicket(closeChangeRecord, schedule.getScheduleId(), changeId);
+ }
+
+ public void cancelTicket(Schedule schedule, ChangeManagementSchedule cms, String changeId) throws CMSException {
+ Map<String, Object> variables = getCancelVariables(schedule, changeId);
+ JsonNode cancelChangeRecord = buildCreateRequest.createCancelChangeRecord(variables);
+ debug.debug("cancelChangeRecord=" + cancelChangeRecord.toString());
+ postCloseChangeTicket(cancelChangeRecord, schedule.getScheduleId(), changeId);
+ }
+
+ public void updateTicket(Schedule schedule, ChangeManagementSchedule cms, String changeId) throws CMSException {
+ Map<String, Object> variables = getUpdateVariables(schedule, changeId);
+ JsonNode updateChangeRecord = buildCreateRequest.createUpdateChangeRecord(variables);
+ debug.debug("updateChangeRecord=" + updateChangeRecord.toString());
+ postUpdateChangeTicket(updateChangeRecord, schedule.getScheduleId(), changeId);
+ }
+
+ public TmChangeInfo getChangeTicket(String changeId) {
+ Map<String, String> mdcSave = Mdc.save();
+ try {
+ Map<String, Object> variables = new HashMap<>();
+ variables.put("changeId", changeId);
+ JsonNode getChangeRecord = buildCreateRequest.createUpdateChangeRecord(variables);
+ Response response = tmPost(Endpoint.GET, getChangeRecord, UUID.randomUUID().toString());
+ switch (response.getStatus()) {
+ case 200: {
+ TmChangeInfo resp = response.readEntity(TmChangeInfo.class);
+ if (resp != null) {
+ return resp;
+ }
+ }
+ break;
+ default: {
+ errors.error(LogMessages.UNEXPECTED_RESPONSE, "TM", String.valueOf(response.getStatus()),
+ response.toString());
+ }
+ }
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e.toString());
+ } finally {
+ Mdc.restore(mdcSave);
+ }
+ return null;
+ }
+
+ private Map<String, Object> getCloseVariables(Schedule schedule, ChangeManagementGroup group,
+ List<ChangeManagementSchedule> cmSchedules, String changeId, ClosureCode closureCode,
+ String closingComments) {
+ String requesterId = schedule.getUserId();
+ Map<String, Object> variables = new HashMap<String, Object>();
+ if (requesterId.length() > Variables.requesterId.getMaxLength())
+ requesterId = requesterId.substring(0, Variables.requesterId.getMaxLength());
+ long actualStartDate = 0;
+ long actualEndDate = 0;
+ for (ChangeManagementSchedule cms : cmSchedules) {
+ if (cms.getDispatchTimeMillis() != null)
+ if (actualStartDate == 0 || cms.getDispatchTimeMillis() < actualStartDate)
+ actualStartDate = cms.getDispatchTimeMillis();
+ if (cms.getExecutionCompletedTimeMillis() != null)
+ if (cms.getExecutionCompletedTimeMillis() > actualEndDate)
+ actualEndDate = cms.getExecutionCompletedTimeMillis();
+ }
+ if (closureCode != ClosureCode.Successful) {
+ if (actualEndDate == 0)
+ actualEndDate = System.currentTimeMillis();
+ if (actualStartDate == 0)
+ actualStartDate = actualEndDate - 1000;
+
+ }
+ variables.put(Variables.status.toString(), "Closed");
+ variables.put(Variables.requesterId.toString(), requesterId);
+ variables.put(Variables.actualStartDate.toString(), actualStartDate / 1000);
+ variables.put(Variables.actualEndDate.toString(), actualEndDate / 1000);
+ variables.put(Variables.changeId.toString(), changeId);
+ variables.put(Variables.closureCode.toString(), closureCode.toString());
+ variables.put(Variables.closingComments.toString(), closingComments);
+ return variables;
+ }
+
+ private Map<String, Object> getCancelVariables(Schedule schedule, String changeId) {
+ String requesterId = schedule.getUserId();
+ Map<String, Object> variables = new HashMap<String, Object>();
+ if (requesterId.length() > Variables.requesterId.getMaxLength())
+ requesterId = requesterId.substring(0, Variables.requesterId.getMaxLength());
+ variables.put(Variables.requesterId.toString(), requesterId);
+ variables.put(Variables.changeId.toString(), changeId);
+ return variables;
+ }
+
+ private Map<String, Object> getUpdateVariables(Schedule schedule, String changeId) {
+ String requesterId = schedule.getUserId();
+ Map<String, Object> variables = new HashMap<String, Object>();
+ if (requesterId.length() > Variables.requesterId.getMaxLength())
+ requesterId = requesterId.substring(0, Variables.requesterId.getMaxLength());
+ variables.put(Variables.requesterId.toString(), requesterId);
+ variables.put(Variables.changeId.toString(), changeId);
+ return variables;
+ }
+
+ private void postCloseChangeTicket(JsonNode closeChangeRecord, String scheduleId, String changeId)
+ throws CMSException {
+ Map<String, String> mdcSave = Mdc.save();
+ try {
+ Response response = null;
+ debug.debug("postCloseChangeTicket {}", closeChangeRecord.asText());
+ log.info(LogMessages.TM_CLOSE_CHANGE_RECORD, "Begin", scheduleId, changeId);
+ // response = vtmPost(url, closeChangeRecord, scheduleId);
+ response = tmPost(Endpoint.CLOSE, closeChangeRecord, scheduleId);
+ log.info(LogMessages.TM_CLOSE_CHANGE_RECORD, "End", scheduleId, changeId);
+ switch (response.getStatus()) {
+ case 200: {
+ String resp = response.readEntity(String.class);
+ debug.debug("response=" + resp.toString());
+ }
+ break;
+ case 400: {
+ String respString = response.readEntity(String.class);
+ debug.debug("response=" + respString);
+ if (!isAlreadyClosed(respString)) {
+ errors.error(LogMessages.UNEXPECTED_RESPONSE, "vTM", String.valueOf(response.getStatus()),
+ response.toString() + " : " + respString);
+ throw new CMSException(Status.PRECONDITION_FAILED, LogMessages.UNABLE_TO_CLOSE_CHANGE_TICKET,
+ scheduleId, changeId, respString);
+ }
+ }
+ break;
+ default: {
+ String message = response.readEntity(String.class);
+ errors.error(LogMessages.UNEXPECTED_RESPONSE, "vTM", String.valueOf(response.getStatus()),
+ response.toString() + " : " + message);
+ throw new CMSException(Status.PRECONDITION_FAILED, LogMessages.UNABLE_TO_CLOSE_CHANGE_TICKET,
+ scheduleId, changeId, message);
+ }
+ }
+ } catch (ProcessingException e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ throw new CMSException(Status.PRECONDITION_FAILED, LogMessages.UNABLE_TO_CLOSE_CHANGE_TICKET, scheduleId,
+ changeId, e.toString());
+ } finally {
+ Mdc.restore(mdcSave);
+ }
+
+ }
+
+ private boolean isAlreadyClosed(String respString) {
+ try {
+ ObjectMapper om = new ObjectMapper();
+ ObjectNode resp = om.readValue(respString, ObjectNode.class);
+ if (resp != null) {
+ debug.debug("resp=" + resp.toString());
+ ArrayNode errs = (ArrayNode) resp.get("serviceException");
+ if (errs != null) {
+ for (JsonNode jn : errs) {
+ ObjectNode on = (ObjectNode) jn;
+ String messageId = on.get("messageId").asText();
+ String text = on.get("text").asText();
+ if (messageId.equals("SVC40006") && text.contains("is in Closed status")) {
+ return true;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ }
+ return false;
+ }
+
+ private List<TmAsset> getAssetList(List<String> vnfNames) {
+ List<TmAsset> assetList = new ArrayList<TmAsset>();
+ for (String vnfName : vnfNames) {
+ TmAsset asset = new TmAsset();
+ asset.setAssetId(vnfName);
+ assetList.add(asset);
+ }
+ return assetList;
+ }
+
+ private Map<String, Object> getVariables(Schedule schedule, ChangeManagementGroup group, List<String> vnfNames,
+ List<DomainData> domainData) {
+ Long plannedStartDate = group.getStartTimeMillis();
+ Long plannedEndDate = group.getFinishTimeMillis();
+ Long validationStartTime = plannedStartDate + group.getNormalDurationInSecs();
+ Long backoutStartTime = plannedEndDate - group.getAdditionalDurationInSecs();
+ String requesterId = schedule.getUserId();
+ Map<String, Object> variables = new HashMap<String, Object>();
+
+ String vnfList = vnfNames.toString();
+ if (vnfList.length() > Variables.vnfList.getMaxLength())
+ vnfList = vnfList.substring(0, Variables.vnfList.getMaxLength());
+ if (requesterId.length() > Variables.requesterId.getMaxLength())
+ requesterId = requesterId.substring(0, Variables.requesterId.getMaxLength());
+
+ variables.put(Variables.vnfList.toString(), vnfList);
+ variables.put(Variables.vnfName.toString(), vnfNames.get(0));
+ variables.put(Variables.requesterId.toString(), requesterId);
+ variables.put(Variables.plannedStartDate.toString(), plannedStartDate / 1000);
+ variables.put(Variables.plannedEndDate.toString(), plannedEndDate / 1000);
+ variables.put(Variables.validationStartTime.toString(), validationStartTime / 1000);
+ variables.put(Variables.backoutStartTime.toString(), backoutStartTime / 1000);
+ // These will be display UTC -
+ variables.put(Variables.validationStartTimeDisplay.toString(),
+ ISODateTimeFormat.dateTimeNoMillis().print(validationStartTime));
+ variables.put(Variables.backoutStartTimeDisplay.toString(),
+ ISODateTimeFormat.dateTimeNoMillis().print(backoutStartTime));
+ variables.put(Variables.plannedStartTimeDisplay.toString(),
+ ISODateTimeFormat.dateTimeNoMillis().print(plannedStartDate));
+ variables.put(Variables.plannedEndTimeDisplay.toString(),
+ ISODateTimeFormat.dateTimeNoMillis().print(plannedEndDate));
+
+ // Ticket field values can be passed in via the DomainData
+ JsonNode defaultValues = buildCreateRequest.getYaml("DefaultChangeTicketProperties");
+ Iterator<String> names = defaultValues.fieldNames();
+ while (names.hasNext()) {
+ String name = names.next();
+ JsonNode valueNode = defaultValues.get(name);
+ String value = valueNode.asText("");
+ variables.put("dd." + name, value);
+ }
+
+ // Override defaults from the request.
+ for (DomainData dd : domainData) {
+ String name = dd.getName();
+ String value = dd.getValue();
+ variables.put("dd." + name, value);
+ }
+ // Allow values to be templates as well
+ // Did this so plans: ${dd.workflowName}
+ for (String name : variables.keySet()) {
+ Object value = variables.get(name);
+ if (value instanceof String) {
+ StrSubstitutor sub = new StrSubstitutor(variables);
+ value = sub.replace(value.toString());
+ variables.put(name, value);
+ }
+ }
+ return variables;
+
+ }
+
+ private String postCreateChangeTicket(JsonNode createChangeRecord, String scheduleId) throws CMSException {
+ String changeId = null;
+ Map<String, String> mdcSave = Mdc.save();
+ try {
+ Response response = null;
+ debug.debug("postCreateChangeTicket {}", createChangeRecord.toString());
+ log.info(LogMessages.TM_CREATE_CHANGE_RECORD, "Begin", scheduleId);
+ // response = vtmPost(url, createChangeRecord, scheduleId);
+ response = tmPost(Endpoint.CREATE, createChangeRecord, scheduleId);
+ log.info(LogMessages.TM_CREATE_CHANGE_RECORD, "End", scheduleId);
+ switch (response.getStatus()) {
+ case 200: {
+ ObjectNode json = response.readEntity(ObjectNode.class);
+ if (json != null) {
+ debug.debug("Message returned by vTM " + json.toString());
+ }
+ if (json != null && json.get("changeId") != null) {
+ changeId = json.get("changeId").textValue();
+ if (changeId != null) {
+ debug.debug("ChangeId=" + changeId);
+ }
+ } else {
+ errors.error(LogMessages.UNEXPECTED_RESPONSE, "vTM", String.valueOf(response.getStatus()),
+ response.toString() + " : " + "Response is empty");
+ throw new CMSException(Status.EXPECTATION_FAILED, LogMessages.UNABLE_TO_CREATE_CHANGE_TICKET,
+ scheduleId, "Response is empty");
+ }
+ }
+ break;
+ default: {
+ String message = response.readEntity(String.class);
+ errors.error(LogMessages.UNEXPECTED_RESPONSE, "vTM", String.valueOf(response.getStatus()),
+ response.toString() + " : " + message);
+ throw new CMSException(Status.EXPECTATION_FAILED, LogMessages.UNABLE_TO_CREATE_CHANGE_TICKET,
+ scheduleId, message);
+ }
+ }
+ } catch (ProcessingException e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ throw new CMSException(Status.EXPECTATION_FAILED, LogMessages.UNABLE_TO_CREATE_CHANGE_TICKET, scheduleId,
+ e.toString());
+ } finally {
+ Mdc.restore(mdcSave);
+ }
+ return changeId;
+ }
+
+ private String postUpdateChangeTicket(JsonNode updateChangeRecord, String scheduleId, String changeId)
+ throws CMSException {
+ Map<String, String> mdcSave = Mdc.save();
+ try {
+ String url = env.getProperty("vtm.url") + env.getProperty("vtm.updatePath");
+
+ Response response = null;
+ debug.debug("postUpdateChangeTicket {}", updateChangeRecord.toString());
+ log.info(LogMessages.TM_UPDATE_CHANGE_RECORD, "Begin", scheduleId, changeId, url);
+ // response = vtmPost(url, updateChangeRecord, scheduleId);
+ response = tmPost(Endpoint.UPDATE, updateChangeRecord, scheduleId);
+ log.info(LogMessages.TM_UPDATE_CHANGE_RECORD, "End", scheduleId, changeId, url);
+ switch (response.getStatus()) {
+ case 200: {
+ String resp = response.readEntity(String.class);
+ debug.debug("response=" + resp.toString());
+ }
+ break;
+ default: {
+ String message = response.readEntity(String.class);
+ errors.error(LogMessages.UNEXPECTED_RESPONSE, "vTM", String.valueOf(response.getStatus()),
+ response.toString() + " : " + message);
+ throw new CMSException(Status.PRECONDITION_FAILED, LogMessages.UNABLE_TO_UPDATE_CHANGE_TICKET,
+ scheduleId, changeId, message);
+ }
+ }
+ } catch (ProcessingException e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ throw new CMSException(Status.PRECONDITION_FAILED, LogMessages.UNABLE_TO_UPDATE_CHANGE_TICKET, scheduleId,
+ changeId, e.toString());
+ } finally {
+ Mdc.restore(mdcSave);
+ }
+ return changeId;
+ }
+
+ private Response vtmPostOld(String url, Object request, String scheduleId) throws CMSException {
+ Response response = null;
+ try {
+ String user = env.getProperty("vtm.user");
+ String pass = pm.getProperty("vtm.pass", "");
+ // Cannot provide changeId. Interesting.
+ // This should be replaced by fetch
+ // For now, make a best effort to get the passed changeId
+
+ Client client = ClientBuilder.newClient();
+ client.register(new BasicAuthenticatorFilter(user, pass));
+ client.register(new CMSOClientFilters());
+ WebTarget target = client.target(url);
+ Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON);
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonRequest = mapper.writeValueAsString(request);
+ debug.debug("vTM URL = " + url + " user=" + user + " : " + jsonRequest);
+ Mdc.metricStart(scheduleId, url);
+ response = invocationBuilder.post(Entity.json(request));
+ Mdc.metricEnd(response);
+ metrics.info(LogMessages.TM_API, url);
+ // String message = response.readEntity(String.class);
+ // debug.debug("Return from " + url + " : " + response.toString() + "\n" +
+ // message);
+ debug.debug("Return from " + url + " : " + response.toString());
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString());
+ throw new CMSException(Status.INTERNAL_SERVER_ERROR, LogMessages.UNABLE_TO_CREATE_CHANGE_TICKET, scheduleId,
+ e.getMessage());
+ }
+ return response;
+ }
+
+ private Response tmPost(Endpoint ep, Object request, String scheduleId) throws CMSException {
+ Response response = null;
+ List<String> endpoints = new ArrayList<>();
+ String url = tmEndpoints.getEndpoint(ep, endpoints);
+ while (url != null) {
+ try {
+ String user = env.getProperty("mechid.user");
+ String pass = pm.getProperty("mechid.pass", "");
+ // Cannot provide changeId. Interesting.
+ // This should be replaced by fetch
+ // For now, make a best effort to get the passed changeId
+
+ Client client = ClientBuilder.newClient();
+ client.register(new BasicAuthenticatorFilter(user, pass));
+ client.register(new CMSOClientFilters());
+ WebTarget target = client.target(url);
+ Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON);
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonRequest = mapper.writeValueAsString(request);
+ debug.debug("TM URL = " + url + " user=" + user + " : " + jsonRequest);
+ Mdc.metricStart(scheduleId, url);
+ response = invocationBuilder.post(Entity.json(request));
+ Mdc.metricEnd(response);
+ metrics.info(LogMessages.TM_API, url);
+ // String message = response.readEntity(String.class);
+ // debug.debug("Return from " + url + " : " + response.toString() + "\n" +
+ // message);
+ debug.debug("Return from " + url + " : " + response.toString());
+ return response;
+ } catch (ProcessingException e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString());
+ url = tmEndpoints.getNextEndpoint(ep, endpoints);
+ if (url == null || !tryNextURL(e)) {
+ throw new CMSException(Status.INTERNAL_SERVER_ERROR, LogMessages.UNABLE_TO_CREATE_CHANGE_TICKET,
+ scheduleId, e.getMessage());
+ }
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString());
+ throw new CMSException(Status.INTERNAL_SERVER_ERROR, LogMessages.UNABLE_TO_CREATE_CHANGE_TICKET,
+ scheduleId, e.getMessage());
+ }
+ }
+ return response;
+ }
+
+ private boolean tryNextURL(ProcessingException e) {
+ if (e.getCause() instanceof UnknownHostException)
+ return true;
+ return true;
+ }
+
+ public HealthCheckComponent healthCheck() {
+ // No op
+ HealthCheckComponent hcc = new HealthCheckComponent();
+ hcc.setName("TM Interface");
+ hcc.setUrl("");
+ hcc.setHealthy(true);
+ hcc.setStatus("OK");
+ return hcc;
+ }
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmEndpoints.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmEndpoints.java
new file mode 100644
index 0000000..b72eef4
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmEndpoints.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.ticketmgt;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+@Component
+public class TmEndpoints {
+ private static EELFLogger log = EELFManager.getInstance().getLogger(TmEndpoints.class);
+ private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();
+ private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();
+
+ @Autowired
+ Environment env;
+
+ //
+ // This class was desinged to support a list of endpoints for each interface
+ // to support failover to alternate endpoints.
+ // This has been gutted so that only a single endpoint for each
+ // interface is loaded from the environment.
+ //
+ public enum Endpoint {
+ GET("tm.getPath"), CREATE("tm.createPath"), CLOSE("tm.closePath"), UPDATE("tm.updatePath"),;
+ private final String pathName;
+
+ private Endpoint(String pathname) {
+ this.pathName = pathname;
+ }
+
+ @Override
+ public String toString() {
+ return pathName;
+ }
+ }
+
+ private boolean legacyLoaded = false;
+ private Map<Endpoint, List<String>> endpointMap = new HashMap<>();
+ private Map<Endpoint, String> endpointMapOK = new HashMap<>();
+
+ public String getEndpoint(Endpoint ep, List<String> endpoints) {
+ loadLegacy();
+ endpoints.clear();
+ endpoints.addAll(endpointMap.get(ep));
+ String endpoint = null;
+ if (endpoints.size() > 0) {
+ // Make an attempt to return the most recent "working" endpoint.
+ //
+ synchronized (endpointMapOK) {
+ endpoint = endpointMapOK.get(ep);
+ if (endpoint == null) {
+ endpoint = endpoints.get(0);
+ endpointMapOK.put(ep, endpoint);
+ }
+ }
+ endpoints.remove(endpoint);
+ }
+ return endpoint;
+ }
+
+ // Call this if the previous enpoint failed to connect.
+ // An attempt to track the most recent "working" endpoint.
+ public String getNextEndpoint(Endpoint ep, List<String> endpoints) {
+ String endpoint = null;
+ if (endpoints.size() > 0) {
+ endpoint = endpoints.remove(0);
+ synchronized (endpointMapOK) {
+ // Let's hope this one works.
+ endpointMapOK.put(ep, endpoint);
+ }
+ }
+ return endpoint;
+ }
+
+ private synchronized void loadLegacy() {
+ if (legacyLoaded)
+ return;
+ log.info("Loading legacy endpoints");
+ endpointMap = new HashMap<>();
+ addToEndpointMap(Endpoint.CREATE);
+ addToEndpointMap(Endpoint.GET);
+ addToEndpointMap(Endpoint.UPDATE);
+ addToEndpointMap(Endpoint.CLOSE);
+ }
+
+ private void addToEndpointMap(Endpoint ep) {
+ List<String> list = endpointMap.get(ep);
+ if (list == null) {
+ list = new ArrayList<>();
+ endpointMap.put(ep, list);
+ }
+ list.add(env.getProperty(ep.toString()));
+ }
+
+ public String toString() {
+ return endpointMap.toString();
+ }
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmStatusClient.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmStatusClient.java
new file mode 100644
index 0000000..e5c14b1
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmStatusClient.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.ticketmgt;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.transaction.Transactional;
+import org.onap.optf.cmso.common.CMSStatusEnum;
+import org.onap.optf.cmso.common.LogMessages;
+import org.onap.optf.cmso.common.exceptions.CMSException;
+import org.onap.optf.cmso.model.ChangeManagementGroup;
+import org.onap.optf.cmso.model.ChangeManagementSchedule;
+import org.onap.optf.cmso.model.Schedule;
+import org.onap.optf.cmso.model.dao.ChangeManagementGroupDAO;
+import org.onap.optf.cmso.model.dao.ChangeManagementScheduleDAO;
+import org.onap.optf.cmso.model.dao.ScheduleDAO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+
+@Component
+public class TmStatusClient {
+ private static EELFLogger log = EELFManager.getInstance().getLogger(TmStatusClient.class);
+ private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();
+ private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();
+
+ public enum GroupAuditStatus {
+ InProgress, Completed, CompletedWithErrors
+ }
+
+ public enum ClosureCode {
+ // Map to TM closure codes
+ Successful("Successful As Scheduled"), Unsuccessful("Unsuccessful");
+
+ private final String closureCode;
+
+ private ClosureCode(String code) {
+ closureCode = code;
+ }
+
+ @Override
+ public String toString() {
+ return closureCode;
+ }
+ }
+
+ @Autowired
+ Environment env;
+
+ @Autowired
+ ScheduleDAO scheduleDAO;
+
+ @Autowired
+ ChangeManagementScheduleDAO cmScheduleDAO;
+
+ @Autowired
+ ChangeManagementGroupDAO cmGroupDAO;
+
+ @Autowired
+ TmClient tmClient;
+
+ @Transactional
+ public void checkStatus(Integer id) {
+ debug.debug("Entered checkStatus id=" + id);
+ try {
+ // Multiple cmso instance support - re-get the record with a Schedule lock
+ Schedule s = scheduleDAO.lockOne(id);
+ if (!s.getStatus().equals(CMSStatusEnum.NotificationsInitiated.toString())) {
+ debug.debug(s.getScheduleId() + " is no longer in " + CMSStatusEnum.NotificationsInitiated.toString()
+ + " : it is " + s.getStatus());
+ // Attempt at avoiding race condition in a load balance env. ?
+ return;
+ }
+ Map<GroupAuditStatus, List<ChangeManagementGroup>> groupStatus =
+ new HashMap<GroupAuditStatus, List<ChangeManagementGroup>>();
+ List<ChangeManagementGroup> groups = cmGroupDAO.findBySchedulesID(id);
+
+ // Close tickets for completed VNFs
+ for (ChangeManagementGroup group : groups) {
+ processGroup(s, group);
+ }
+
+ // Check overall status of schedule.
+ //
+ for (ChangeManagementGroup group : groups) {
+ GroupAuditStatus status = auditGroupStatus(s, group);
+ List<ChangeManagementGroup> list = groupStatus.get(status);
+ if (list == null) {
+ list = new ArrayList<ChangeManagementGroup>();
+ groupStatus.put(status, list);
+ }
+ list.add(group);
+ }
+ // In progress
+ if (groupStatus.containsKey(GroupAuditStatus.InProgress))
+ return;
+ //
+ if (groupStatus.containsKey(GroupAuditStatus.CompletedWithErrors)) {
+ s.setStatus(CMSStatusEnum.CompletedWithError.toString());
+ }
+ if (groupStatus.containsKey(GroupAuditStatus.Completed)) {
+ s.setStatus(CMSStatusEnum.Completed.toString());
+ }
+ scheduleDAO.save(s);
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ String msg = EELFResourceManager.format(LogMessages.UNEXPECTED_EXCEPTION, e.getMessage());
+ errors.warn(msg, e);
+ }
+ }
+
+ private void processGroup(Schedule s, ChangeManagementGroup group) throws CMSException {
+ debug.debug("{Processing status of " + s.getScheduleId() + " group=" + group.getGroupId());
+ // Get status of all VNFs within a ticket within the group (Tickets will not
+ // span groups)
+ Map<String, List<ChangeManagementSchedule>> failed = new HashMap<String, List<ChangeManagementSchedule>>();
+ Map<String, List<ChangeManagementSchedule>> inProgress = new HashMap<String, List<ChangeManagementSchedule>>();
+ Map<String, List<ChangeManagementSchedule>> completed = new HashMap<String, List<ChangeManagementSchedule>>();
+ Map<String, List<ChangeManagementSchedule>> tmClosed = new HashMap<String, List<ChangeManagementSchedule>>();
+ List<ChangeManagementSchedule> cmSchedules = cmScheduleDAO.findByChangeManagementGroupId(group.getId());
+ for (ChangeManagementSchedule cmSchedule : cmSchedules) {
+ String status = cmSchedule.getStatus();
+ String changeId = cmSchedule.getTmChangeId();
+ String tmStatus = cmSchedule.getTmStatus();
+ CMSStatusEnum cmsStatus = CMSStatusEnum.Completed.fromString(status);
+ switch (cmsStatus) {
+ case Scheduled:
+ case Triggered:
+ addTo(inProgress, cmSchedule);
+ break;
+ case Failed:
+ case PastDue:
+ case Error:
+ case Cancelled:
+ case SchedulingFailed:
+ case Deleted:
+ addTo(failed, cmSchedule);
+ break;
+ case Completed:
+ addTo(completed, cmSchedule);
+ break;
+ case ApprovalRejected:
+ case PendingApproval:
+ case PendingSchedule:
+ case ScheduledImmediate:
+ default:
+ errors.applicationEvent(
+ "Unexpected Change Management schedule event status {0} encountered after notification : scheduleId={1} vnfName={2}",
+ status, s.getScheduleId(), cmSchedule.getVnfName());
+ break;
+ }
+ if (tmStatus != null && tmStatus.equals("Closed"))
+ addTo(tmClosed, cmSchedule);
+ }
+ debug.debug("{Status of " + s.getScheduleId() + " Group " + group.getGroupId() + "\ncompleted="
+ + completed.keySet().toString() + "\ninProgress=" + inProgress.keySet().toString() + "\nfailed="
+ + failed.keySet().toString() + "\ntmCLosed=" + tmClosed.keySet().toString());
+
+ // Remove all tickets from completed where there are still 'Triggered' VNFs
+ for (String changeId : inProgress.keySet())
+ completed.remove(changeId);
+ // Remove all tickets from completed where the ticket is already closed.
+ for (String changeId : tmClosed.keySet())
+ completed.remove(changeId);
+
+ // Do not know what to do with failed
+ for (String changeId : failed.keySet()) {
+ completed.remove(changeId);
+ closeTheTicket(s, group, changeId, failed.get(changeId), ClosureCode.Unsuccessful,
+ "Change management request failed for one or more VNFs");
+ }
+
+ // Remaining completed tickets should be closed
+ debug.debug("{Final status of " + s.getScheduleId() + " Group " + group.getGroupId() + "\ncompleted="
+ + completed.keySet().toString() + "\ninProgress=" + inProgress.keySet().toString() + "\nfailed="
+ + failed.keySet().toString() + "\ntmCLosed=" + tmClosed.keySet().toString());
+ for (String changeId : completed.keySet()) {
+ closeTheTicket(s, group, changeId, completed.get(changeId), ClosureCode.Successful,
+ ClosureCode.Successful.toString());
+ }
+
+ }
+
+ private GroupAuditStatus auditGroupStatus(Schedule s, ChangeManagementGroup group) {
+ // Determine group status and synchronize VNF status with Ticket status.
+ Map<String, List<ChangeManagementSchedule>> failed = new HashMap<String, List<ChangeManagementSchedule>>();
+ Map<String, List<ChangeManagementSchedule>> inProgress = new HashMap<String, List<ChangeManagementSchedule>>();
+ Map<String, List<ChangeManagementSchedule>> completed = new HashMap<String, List<ChangeManagementSchedule>>();
+ Map<String, List<ChangeManagementSchedule>> tmClosed = new HashMap<String, List<ChangeManagementSchedule>>();
+ Set<String> vnfNames = new HashSet<String>();
+ Set<String> allNames = new HashSet<String>();
+ Set<String> failedNames = new HashSet<String>();
+ Set<String> completedNames = new HashSet<String>();
+ Long startDate = group.getStartTimeMillis();
+ List<ChangeManagementSchedule> cmSchedules = cmScheduleDAO.findByChangeManagementGroupId(group.getId());
+ for (ChangeManagementSchedule cmSchedule : cmSchedules) {
+ String vnfName = cmSchedule.getVnfName();
+ vnfNames.add(vnfName);
+ allNames.add(vnfName);
+ String status = cmSchedule.getStatus();
+ String tmStatus = cmSchedule.getTmStatus();
+ CMSStatusEnum cmsStatus = CMSStatusEnum.Completed.fromString(status);
+ switch (cmsStatus) {
+ case Scheduled:
+ case Triggered:
+ addTo(inProgress, cmSchedule);
+ break;
+ case Failed:
+ case PastDue:
+ case Error:
+ case Cancelled:
+ case SchedulingFailed:
+ case Deleted:
+ failedNames.add(vnfName);
+ addTo(failed, cmSchedule);
+ break;
+ case Completed:
+ completedNames.add(vnfName);
+ addTo(completed, cmSchedule);
+ break;
+ case ApprovalRejected:
+ case PendingApproval:
+ case PendingSchedule:
+ case ScheduledImmediate:
+ default:
+ errors.applicationEvent(
+ "Unexpected Change Management schedule event status {0} encountered after notification : scheduleId={1} vnfName={2}",
+ status, s.getScheduleId(), cmSchedule.getVnfName());
+ break;
+ }
+ if (tmStatus != null && tmStatus.equals("Closed"))
+ addTo(tmClosed, cmSchedule);
+ }
+
+ // We have at least 1 ticket with VNFs in progress. Leave schedule status as is.
+ if (inProgress.size() > 0)
+ return GroupAuditStatus.InProgress;
+
+ // All VNFs are either failed or completed (or there is a bug.)
+
+ allNames.removeAll(completedNames);
+ if (allNames.size() == 0) {
+ return GroupAuditStatus.Completed;
+ }
+ allNames.removeAll(failedNames);
+ if (allNames.size() == 0) {
+ return GroupAuditStatus.CompletedWithErrors;
+ }
+ return null;
+ }
+
+ private void addTo(Map<String, List<ChangeManagementSchedule>> map, ChangeManagementSchedule cmSchedule) {
+ String status = cmSchedule.getStatus();
+ String changeId = cmSchedule.getTmChangeId();
+ List<ChangeManagementSchedule> list = map.get(changeId);
+ if (list == null) {
+ list = new ArrayList<ChangeManagementSchedule>();
+ map.put(changeId, list);
+ }
+ list.add(cmSchedule);
+
+ }
+
+ private void closeTheTicket(Schedule s, ChangeManagementGroup group, String changeId,
+ List<ChangeManagementSchedule> list, ClosureCode closureCode, String closingComments) throws CMSException {
+ debug.debug("Closing ticket " + changeId + ":" + closureCode);
+ try {
+ tmClient.closeTicket(s, group, list, changeId, closureCode, closingComments);
+ for (ChangeManagementSchedule cms : list) {
+ cms.setTmStatus("Closed");
+ cmScheduleDAO.save(cms);
+ }
+ } catch (CMSException e) {
+ throw e;
+ }
+
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/BuildCreateRequest.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/BuildCreateRequest.java
new file mode 100644
index 0000000..0b7c319
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/BuildCreateRequest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.ticketmgt.bean;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.text.StrSubstitutor;
+import org.onap.optf.cmso.common.LogMessages;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+
+@Component
+public class BuildCreateRequest {
+
+ //
+ // Prototype of a ticket flow... Create/Get(check status)/Update/Close/Cancel
+ // Values here a derived from the scheduling process
+ // Other values derived from ticket templates...
+ // This is for example purposes only ans every provider
+ // will have unique requirements.
+ // This assumes multiple VNFs can appear on a single ticket
+ //
+ public enum Variables {
+ vnfList(168), requesterId(50), plannedStartDate(15), plannedEndDate(15), validationStartTime(
+ 0), backoutStartTime(0), assetList(0), validationStartTimeDisplay(0), backoutStartTimeDisplay(
+ 0), plannedStartTimeDisplay(0), plannedEndTimeDisplay(0), vnfName(0), changeId(
+ 15), actualStartDate(
+ 15), actualEndDate(15), status(0), closureCode(30), closingComments(1332),;
+ private final int maxLength;
+
+ private Variables(int max) {
+ this.maxLength = max;
+ }
+
+ public int getMaxLength() {
+ return maxLength;
+ }
+ }
+
+ private static EELFLogger log = EELFManager.getInstance().getLogger(BuildCreateRequest.class);
+ private static EELFLogger metrics = EELFManager.getInstance().getMetricsLogger();
+ private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();
+ private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();
+
+ @Autowired
+ Environment env;
+
+ public JsonNode createChangeRecordRequest(Map<String, Object> variables, List<TmAsset> assetList,
+ String workflowName) {
+ JsonNode rawjson = getYaml("CreateChangeTicket");
+ JsonNode json = substituteJson(rawjson, variables);
+ return json;
+ }
+
+ public JsonNode createCloseCancelChangeRecord(Map<String, Object> variables) {
+ JsonNode rawjson = getYaml("CloseCancelChangeRecord");
+ JsonNode json = substituteJson(rawjson, variables);
+ return json;
+ }
+
+ public JsonNode createCancelChangeRecord(Map<String, Object> variables) {
+ JsonNode rawjson = getYaml("CancelChangeRecord");
+ JsonNode json = substituteJson(rawjson, variables);
+ return json;
+ }
+
+ public JsonNode createUpdateChangeRecord(Map<String, Object> variables) {
+ JsonNode rawjson = getYaml("UpdateChangeRecord");
+ JsonNode json = substituteJson(rawjson, variables);
+ return json;
+ }
+
+ public JsonNode createGetChangeRecord(Map<String, Object> variables) {
+ JsonNode rawjson = getYaml("GetChangeRecord");
+ JsonNode json = substituteJson(rawjson, variables);
+ return json;
+ }
+
+ private JsonNode substituteJson(JsonNode json, Map<String, Object> variables) {
+ StrSubstitutor sub = new StrSubstitutor(variables);
+ substitute(sub, json, null, null);
+ return json;
+ }
+
+ private void substitute(StrSubstitutor sub, JsonNode json, JsonNode parent, String name) {
+ switch (json.getNodeType()) {
+ case STRING:
+ TextNode tn = (TextNode) json;
+ String value = tn.textValue();
+ updateNode(sub, (ObjectNode) parent, name, value);
+ break;
+ case ARRAY:
+ break;
+ case BINARY:
+ break;
+ case BOOLEAN:
+ break;
+ case MISSING:
+ break;
+ case NULL:
+ break;
+ case NUMBER:
+ break;
+ case OBJECT:
+ ObjectNode objectnode = (ObjectNode) json;
+ Iterator<String> fieldnames = objectnode.fieldNames();
+ while (fieldnames.hasNext()) {
+ String nextName = fieldnames.next();
+ JsonNode jn = objectnode.get(nextName);
+ substitute(sub, jn, json, nextName);
+ }
+ break;
+ case POJO:
+ break;
+ default:
+ }
+
+ }
+
+ private void updateNode(StrSubstitutor sub, ObjectNode parent, String name, String value) {
+ value = sub.replace(value);
+ if (isInteger(name)) {
+ try {
+ parent.put(name, Long.valueOf(value));
+ } catch (Exception e) {
+ errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ parent.put(name, value);
+ }
+ } else {
+ parent.put(name, value);
+ }
+ }
+
+ private boolean isInteger(String name) {
+ if (name.equals(Variables.plannedEndDate.toString()))
+ return true;
+ if (name.equals(Variables.plannedStartDate.toString()))
+ return true;
+ if (name.equals(Variables.actualStartDate.toString()))
+ return true;
+ if (name.equals(Variables.actualEndDate.toString()))
+ return true;
+ return false;
+ }
+
+ public JsonNode getYaml(String workflowName) {
+ JsonNode json = null;
+ // Get the YAML file for this workflow
+ String yamlFile = env.getProperty("tm.template.folder") + File.separator + workflowName + ".yaml";
+ // String yamlFile =
+ // "C:\\cmso\\master\\etc\\config\\templates\\vtm\\questionnaires\\Build
+ // Software Upgrade for vNFs.yaml";
+ try {
+ ObjectMapper om = new ObjectMapper(new YAMLFactory());
+ File file = new File(yamlFile);
+ json = om.readTree(file);
+ } catch (Exception e) {
+ debug.debug("Unexpected exception reading : (0} ", yamlFile, e);
+ }
+ return json;
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmApprovalStatusEnum.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmApprovalStatusEnum.java
new file mode 100644
index 0000000..9b004f9
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmApprovalStatusEnum.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.ticketmgt.bean;
+
+public enum TmApprovalStatusEnum {
+ ApprovalRequired("Approval Required"), PendingApproval("Pending Approval"), Rejected("Rejected"), Approved(
+ "Approved"), ApprovalProcessCancelled(
+ "Approval Process Cancelled"), NotRequired("Not Required"), Clear("Clear"),;
+ private final String text;
+
+ private TmApprovalStatusEnum(String text) {
+ this.text = text;
+ }
+
+ public String toString() {
+ return this.text;
+ }
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmAsset.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmAsset.java
new file mode 100644
index 0000000..ac2d9b8
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmAsset.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.ticketmgt.bean;
+
+public class TmAsset {
+ String assetId;
+
+ public String getAssetId() {
+ return assetId;
+ }
+
+ public void setAssetId(String assetId) {
+ this.assetId = assetId;
+ }
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmChangeInfo.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmChangeInfo.java
new file mode 100644
index 0000000..03b031a
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmChangeInfo.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.ticketmgt.bean;
+
+public class TmChangeInfo {
+ String changeId;
+ String category;
+ String type;
+ String item;
+ String summary;
+ String status;
+ String approvalStatus;
+ Long plannedStartDate;
+ Long plannedEndDate;
+ Long dateModified;
+ Long actualStartDate;
+ Long actualEndDate;
+
+ public String getChangeId() {
+ return changeId;
+ }
+
+ public void setChangeId(String changeId) {
+ this.changeId = changeId;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getItem() {
+ return item;
+ }
+
+ public void setItem(String item) {
+ this.item = item;
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getApprovalStatus() {
+ return approvalStatus;
+ }
+
+ public void setApprovalStatus(String approvalStatus) {
+ this.approvalStatus = approvalStatus;
+ }
+
+ public Long getPlannedStartDate() {
+ return plannedStartDate;
+ }
+
+ public void setPlannedStartDate(Long plannedStartDate) {
+ this.plannedStartDate = plannedStartDate;
+ }
+
+ public Long getPlannedEndDate() {
+ return plannedEndDate;
+ }
+
+ public void setPlannedEndDate(Long plannedEndDate) {
+ this.plannedEndDate = plannedEndDate;
+ }
+
+ public Long getDateModified() {
+ return dateModified;
+ }
+
+ public void setDateModified(Long dateModified) {
+ this.dateModified = dateModified;
+ }
+
+ public Long getActualStartDate() {
+ return actualStartDate;
+ }
+
+ public void setActualStartDate(Long actualStartDate) {
+ this.actualStartDate = actualStartDate;
+ }
+
+ public Long getActualEndDate() {
+ return actualEndDate;
+ }
+
+ public void setActualEndDate(Long actualEndDate) {
+ this.actualEndDate = actualEndDate;
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmStatusEnum.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmStatusEnum.java
new file mode 100644
index 0000000..dd480b0
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmStatusEnum.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.ticketmgt.bean;
+
+public enum TmStatusEnum {
+ New, Assigned, Planning, Scheduled, WorkInProgress, Pending, Resolved, Closed, Cancelled,
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfChangeManagementResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfChangeManagementResponse.java
new file mode 100644
index 0000000..cdf47f5
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfChangeManagementResponse.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.wf.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WfChangeManagementResponse {
+ List<WfVidCmResponse> cmResponses = new ArrayList<WfVidCmResponse>();
+
+ public List<WfVidCmResponse> getCmResponses() {
+ return cmResponses;
+ }
+
+ public void setCmResponses(List<WfVidCmResponse> cmResponses) {
+ this.cmResponses = cmResponses;
+ }
+
+ public void addCmResponses(WfVidCmResponse cmResponse) {
+ this.cmResponses.add(cmResponse);
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfCmResponse200.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfCmResponse200.java
new file mode 100644
index 0000000..65f2bcc
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfCmResponse200.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.wf.bean;
+
+public class WfCmResponse200 {
+ private Integer status;
+ private WfMsoResponse entity;
+
+ public WfMsoResponse getEntity() {
+ return entity;
+ }
+
+ public void setEntity(WfMsoResponse entity) {
+ this.entity = entity;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoRequestReferences.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoRequestReferences.java
new file mode 100644
index 0000000..56743c3
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoRequestReferences.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.wf.bean;
+
+public class WfMsoRequestReferences {
+ private String instanceId;
+ private String requestId;
+
+ public String getRequestId() {
+ return requestId;
+ }
+
+ public void setRequestId(String requestId) {
+ this.requestId = requestId;
+ }
+
+ public String getInstanceId() {
+ return instanceId;
+ }
+
+ public void setInstanceId(String instanceId) {
+ this.instanceId = instanceId;
+ }
+
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoResponse.java
new file mode 100644
index 0000000..1876c93
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoResponse.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.wf.bean;
+
+public class WfMsoResponse {
+ private WfMsoRequestReferences requestReferences;
+
+ public WfMsoRequestReferences getRequestReferences() {
+ return requestReferences;
+ }
+
+ public void setRequestReferences(WfMsoRequestReferences requestReferences) {
+ this.requestReferences = requestReferences;
+ }
+}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfVidCmResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfVidCmResponse.java
new file mode 100644
index 0000000..395d99d
--- /dev/null
+++ b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfVidCmResponse.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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.
+*/
+
+package org.onap.optf.cmso.wf.bean;
+
+public class WfVidCmResponse {
+ String orchestratorRequestId;
+ String serviceInstanceId;
+ String vnfInstanceId;
+ String vnfName;
+
+ public String getServiceInstanceId() {
+ return serviceInstanceId;
+ }
+
+ public void setServiceInstanceId(String serviceInstanceId) {
+ this.serviceInstanceId = serviceInstanceId;
+ }
+
+ public String getVnfInstanceId() {
+ return vnfInstanceId;
+ }
+
+ public void setVnfInstanceId(String vnfInstanceId) {
+ this.vnfInstanceId = vnfInstanceId;
+ }
+
+ public String getVnfName() {
+ return vnfName;
+ }
+
+ public void setVnfName(String vnfName) {
+ this.vnfName = vnfName;
+ }
+
+ public String getOrchestratorRequestId() {
+ return orchestratorRequestId;
+ }
+
+ public void setOrchestratorRequestId(String orchestratorRequestId) {
+ this.orchestratorRequestId = orchestratorRequestId;
+ }
+
+}