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