Change Management Schedule Optimization 33/67933/1
authorRamaPrasad Amaranarayana (ra5425) <ra5425@att.com>
Wed, 19 Sep 2018 22:41:45 +0000 (18:41 -0400)
committerRamaPrasad Amaranarayana (ra5425) <ra5425@att.com>
Wed, 19 Sep 2018 22:41:45 +0000 (18:41 -0400)
Adding CMSO Service Code for Change Management Schedule Optimization

Change-Id: I502ee905e9197fbb015e36b4181f8aaa2d3eb555
Issue-ID: OPTFRA-353
Signed-off-by: RamaPrasad Amaranarayana (ra5425) <ra5425@att.com>
20 files changed:
cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOClientFilters.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOContainerFilters.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/filters/MessageHeaders.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/so/bean/MsoOrchestrationQueryResponse.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusClient.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusJob.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/sostatus/ScheduleStatusJob.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmClient.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmEndpoints.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmStatusClient.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/BuildCreateRequest.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmApprovalStatusEnum.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmAsset.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmChangeInfo.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmStatusEnum.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfChangeManagementResponse.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfCmResponse200.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoRequestReferences.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoResponse.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfVidCmResponse.java [new file with mode: 0644]

diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOClientFilters.java b/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOClientFilters.java
new file mode 100644 (file)
index 0000000..6396dca
--- /dev/null
@@ -0,0 +1,75 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOContainerFilters.java b/cmso-service/src/main/java/org/onap/optf/cmso/filters/CMSOContainerFilters.java
new file mode 100644 (file)
index 0000000..784ab5a
--- /dev/null
@@ -0,0 +1,128 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/filters/MessageHeaders.java b/cmso-service/src/main/java/org/onap/optf/cmso/filters/MessageHeaders.java
new file mode 100644 (file)
index 0000000..ba3efa3
--- /dev/null
@@ -0,0 +1,105 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/so/bean/MsoOrchestrationQueryResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/so/bean/MsoOrchestrationQueryResponse.java
new file mode 100644 (file)
index 0000000..2e46be0
--- /dev/null
@@ -0,0 +1,76 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusClient.java b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusClient.java
new file mode 100644 (file)
index 0000000..42f282a
--- /dev/null
@@ -0,0 +1,289 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusJob.java b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/MsoStatusJob.java
new file mode 100644 (file)
index 0000000..29853d1
--- /dev/null
@@ -0,0 +1,92 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/ScheduleStatusJob.java b/cmso-service/src/main/java/org/onap/optf/cmso/sostatus/ScheduleStatusJob.java
new file mode 100644 (file)
index 0000000..cd74bc4
--- /dev/null
@@ -0,0 +1,198 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmClient.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmClient.java
new file mode 100644 (file)
index 0000000..b8aed57
--- /dev/null
@@ -0,0 +1,539 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmEndpoints.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmEndpoints.java
new file mode 100644 (file)
index 0000000..b72eef4
--- /dev/null
@@ -0,0 +1,134 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmStatusClient.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/TmStatusClient.java
new file mode 100644 (file)
index 0000000..e5c14b1
--- /dev/null
@@ -0,0 +1,317 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/BuildCreateRequest.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/BuildCreateRequest.java
new file mode 100644 (file)
index 0000000..0b7c319
--- /dev/null
@@ -0,0 +1,202 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmApprovalStatusEnum.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmApprovalStatusEnum.java
new file mode 100644 (file)
index 0000000..9b004f9
--- /dev/null
@@ -0,0 +1,47 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmAsset.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmAsset.java
new file mode 100644 (file)
index 0000000..ac2d9b8
--- /dev/null
@@ -0,0 +1,44 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmChangeInfo.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmChangeInfo.java
new file mode 100644 (file)
index 0000000..03b031a
--- /dev/null
@@ -0,0 +1,144 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmStatusEnum.java b/cmso-service/src/main/java/org/onap/optf/cmso/ticketmgt/bean/TmStatusEnum.java
new file mode 100644 (file)
index 0000000..dd480b0
--- /dev/null
@@ -0,0 +1,36 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfChangeManagementResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfChangeManagementResponse.java
new file mode 100644 (file)
index 0000000..cdf47f5
--- /dev/null
@@ -0,0 +1,52 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfCmResponse200.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfCmResponse200.java
new file mode 100644 (file)
index 0000000..65f2bcc
--- /dev/null
@@ -0,0 +1,54 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoRequestReferences.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoRequestReferences.java
new file mode 100644 (file)
index 0000000..56743c3
--- /dev/null
@@ -0,0 +1,54 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfMsoResponse.java
new file mode 100644 (file)
index 0000000..1876c93
--- /dev/null
@@ -0,0 +1,44 @@
+/*\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
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfVidCmResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/wf/bean/WfVidCmResponse.java
new file mode 100644 (file)
index 0000000..395d99d
--- /dev/null
@@ -0,0 +1,72 @@
+/*\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