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

Change-Id: I83f029c02d990ce607493bf1c008b24a70e804c2
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/service/rs/AdminTool.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/AdminToolImpl.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/BaseSchedulerServiceImpl.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSCallbackImpl.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOService.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOServiceImpl.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOptimizerCallback.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CmQueryParameters.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/HealthCheck.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/HealthCheckImpl.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ApprovalMessage.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CMSInfo.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CMSMessage.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ChangeWindowMessage.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CmDetailsMessage.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CmDomainDataEnum.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/HealthCheckComponent.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/HealthCheckMessage.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ScheduleMessage.java [new file with mode: 0644]
cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/VnfDetailsMessage.java [new file with mode: 0644]

diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/AdminTool.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/AdminTool.java
new file mode 100644 (file)
index 0000000..801986c
--- /dev/null
@@ -0,0 +1,66 @@
+/*\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.service.rs;\r
+\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.ws.rs.DefaultValue;\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.core.Context;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.UriInfo;\r
+import io.swagger.annotations.Api;\r
+import io.swagger.annotations.ApiOperation;\r
+import io.swagger.annotations.ApiParam;\r
+import io.swagger.annotations.ApiResponse;\r
+import io.swagger.annotations.ApiResponses;\r
+\r
+@Api\r
+@Path("/{apiVersion}")\r
+@Produces({MediaType.APPLICATION_JSON})\r
+public interface AdminTool {\r
+\r
+    // ******************************************************************\r
+    @GET\r
+    @Path("/admin/{id}")\r
+    @Produces({MediaType.TEXT_PLAIN})\r
+    @ApiOperation(value = "", notes = "Returns encrypted value of id.", response = String.class)\r
+    @ApiResponses(\r
+            value = {@ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 400, message = "Request failed")})\r
+    public Response exec(@ApiParam(value = "v1|v2") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @ApiParam(value = "Identifier", allowMultiple = true) @PathParam("id") String id, @Context UriInfo uri,\r
+            @Context HttpServletRequest request);\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/AdminToolImpl.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/AdminToolImpl.java
new file mode 100644 (file)
index 0000000..9f1a4d5
--- /dev/null
@@ -0,0 +1,66 @@
+/*\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.service.rs;\r
+\r
+import java.util.UUID;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.UriInfo;\r
+import org.onap.optf.cmso.common.Mdc;\r
+import org.onap.optf.cmso.common.PropertiesManagement;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.stereotype.Controller;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+\r
+@Controller\r
+public class AdminToolImpl implements AdminTool {\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(AdminToolImpl.class);\r
+    private static EELFLogger audit = EELFManager.getInstance().getAuditLogger();\r
+\r
+    @Autowired\r
+    PropertiesManagement pm;\r
+\r
+    @Override\r
+    public Response exec(String apiVersion, String id, UriInfo uri, HttpServletRequest request) {\r
+        Mdc.begin(request, UUID.randomUUID().toString());\r
+        log.info("AdminTool.exec entered");\r
+        if (id.length() < 4)\r
+            return Response.ok("").build();\r
+        String encrypted = pm.getEncryptedValue(id);\r
+        Response response = Response.ok(encrypted).build();\r
+        Mdc.end(response);\r
+        audit.info("AdminTool");\r
+        return response;\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/BaseSchedulerServiceImpl.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/BaseSchedulerServiceImpl.java
new file mode 100644 (file)
index 0000000..8dbafbc
--- /dev/null
@@ -0,0 +1,226 @@
+/*\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.service.rs;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import javax.ws.rs.core.Response.Status;\r
+import org.onap.optf.cmso.common.ApprovalStatusEnum;\r
+import org.onap.optf.cmso.common.CMSStatusEnum;\r
+import org.onap.optf.cmso.common.LogMessages;\r
+import org.onap.optf.cmso.common.exceptions.CMSAlreadyExistsException;\r
+import org.onap.optf.cmso.common.exceptions.CMSException;\r
+import org.onap.optf.cmso.common.exceptions.CMSNotFoundException;\r
+import org.onap.optf.cmso.model.ApprovalType;\r
+import org.onap.optf.cmso.model.DomainData;\r
+import org.onap.optf.cmso.model.Schedule;\r
+import org.onap.optf.cmso.model.ScheduleApproval;\r
+import org.onap.optf.cmso.model.dao.ApprovalTypeDAO;\r
+import org.onap.optf.cmso.model.dao.DomainDataDAO;\r
+import org.onap.optf.cmso.model.dao.ScheduleApprovalDAO;\r
+import org.onap.optf.cmso.model.dao.ScheduleDAO;\r
+import org.onap.optf.cmso.service.rs.models.ApprovalMessage;\r
+import org.onap.optf.cmso.service.rs.models.ScheduleMessage;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.stereotype.Controller;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+\r
+@Controller\r
+public class BaseSchedulerServiceImpl {\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(BaseSchedulerServiceImpl.class);\r
+\r
+    @Autowired\r
+    protected ScheduleDAO scheduleDAO;\r
+\r
+    @Autowired\r
+    DomainDataDAO domainDataDAO;\r
+\r
+    @Autowired\r
+    ApprovalTypeDAO approvalTypeDAO;\r
+\r
+    @Autowired\r
+    ScheduleApprovalDAO scheduleApprovalDAO;\r
+\r
+    protected Schedule validateAndAddScheduleRequest(ScheduleMessage scheduleMessage, List<DomainData> domainData)\r
+            throws CMSException {\r
+        messageValidations(scheduleMessage);\r
+        Schedule s = scheduleDAO.findByDomainScheduleID(scheduleMessage.getDomain(), scheduleMessage.getScheduleId());\r
+\r
+        if (s != null) {\r
+            throw new CMSAlreadyExistsException(scheduleMessage.getDomain(), scheduleMessage.getScheduleId());\r
+        }\r
+        s = new Schedule();\r
+        s.setUserId(scheduleMessage.getUserId());\r
+        s.setCreateDateTimeMillis(System.currentTimeMillis());\r
+        s.setDomain(scheduleMessage.getDomain());\r
+        s.setScheduleId(scheduleMessage.getScheduleId());\r
+        s.setOptimizerTransactionId(s.getScheduleId()); // No reason these cannot be the same as\r
+                                                        // these\r
+                                                        // are 1<=>1 at this\r
+                                                        // point.\r
+        s.setScheduleName(scheduleMessage.getScheduleName());\r
+        s.setScheduleInfo(scheduleMessage.getSchedulingInfo().toString());\r
+        s.setStatus(CMSStatusEnum.PendingSchedule.toString());\r
+        scheduleDAO.save(s);\r
+        for (DomainData dd : domainData) {\r
+            s.addDomainData(dd);\r
+            domainDataDAO.save(dd);\r
+        }\r
+        scheduleDAO.save(s);\r
+        return s;\r
+    }\r
+\r
+    private void messageValidations(ScheduleMessage scheduleMessage) throws CMSException {\r
+        if (scheduleMessage.getScheduleName() == null || scheduleMessage.getScheduleName().equals("")) {\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE, "schedulerName", "");\r
+        }\r
+        if (scheduleMessage.getUserId() == null || scheduleMessage.getUserId().equals("")) {\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE, "userId", "");\r
+        }\r
+    }\r
+\r
+    protected void deleteScheduleRequest(String domain, String scheduleId) throws CMSException {\r
+        Schedule s = scheduleDAO.findByDomainScheduleID(domain, scheduleId);\r
+        if (s == null) {\r
+            throw new CMSNotFoundException(domain, scheduleId);\r
+        }\r
+        CMSStatusEnum currentStatus = CMSStatusEnum.Completed.fromString(s.getStatus());\r
+        s.setDeleteDateTimeMillis(System.currentTimeMillis());\r
+        switch (currentStatus) {\r
+            case Scheduled:\r
+                // TODO CLose all tickets....\r
+                s.setStatus(CMSStatusEnum.Cancelled.toString());\r
+                break;\r
+            case NotificationsInitiated:\r
+                throw new CMSException(Status.NOT_ACCEPTABLE, LogMessages.CANNOT_CANCEL_IN_PROGRESS);\r
+            default:\r
+                s.setStatus(CMSStatusEnum.Deleted.toString());\r
+        }\r
+        scheduleDAO.save(s);\r
+    }\r
+\r
+    protected Schedule processApproval(Schedule s, String domain, ApprovalMessage approvalMessage) throws CMSException {\r
+        String scheduleId = s.getScheduleId();\r
+        ApprovalType approvalType =\r
+                approvalTypeDAO.findByDomainAndType(domain, approvalMessage.getApprovalType().toString());\r
+        if (approvalType == null) {\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_ATTRIBUTE, "approvalType",\r
+                    approvalMessage.getApprovalType().toString());\r
+        }\r
+\r
+        if (!s.getStatus().equals(CMSStatusEnum.PendingApproval.toString())) {\r
+            throw new CMSException(Status.PRECONDITION_FAILED, LogMessages.NOT_PENDING_APPROVAL, domain, scheduleId,\r
+                    s.getStatus());\r
+        }\r
+        if (approvalMessage.getApprovalUserId() == null || approvalMessage.getApprovalUserId().equals("")) {\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE, "userId");\r
+        }\r
+        ScheduleApproval sa = null;\r
+        // only 1 approval per user....\r
+        if (s.getScheduleApprovals() != null) {\r
+            for (ScheduleApproval scheduleApproval : s.getScheduleApprovals()) {\r
+                if (scheduleApproval.getUserId().equals(approvalMessage.getApprovalUserId())\r
+                        && scheduleApproval.getApprovalTypeId().equals(approvalType.getId())) {\r
+                    sa = scheduleApproval;\r
+                }\r
+            }\r
+        }\r
+        if (sa == null) {\r
+            sa = new ScheduleApproval();\r
+            sa.setSchedule(s);\r
+            sa.setApprovalTypeId(approvalType.getId());\r
+            sa.setUserId(approvalMessage.getApprovalUserId());\r
+        }\r
+        // Ignore what time is on the message\r
+        sa.setApprovalDateTimeMillis(System.currentTimeMillis());\r
+        sa.setStatus(approvalMessage.getApprovalStatus().toString());\r
+        sa.setSchedule(s);\r
+        s.addScheduleApproval(sa);\r
+        scheduleDAO.save(s);\r
+        if (sa.getStatus().equals(ApprovalStatusEnum.Rejected.toString())) {\r
+            s.setStatus(CMSStatusEnum.Rejected.toString());\r
+        } else {\r
+            if (allApprovalsReceived(s, sa))\r
+                s.setStatus(CMSStatusEnum.Accepted.toString());\r
+        }\r
+        scheduleDAO.save(s);\r
+        return s;\r
+    }\r
+\r
+    private boolean allApprovalsReceived(Schedule schedule, ScheduleApproval sa) {\r
+        Map<Integer, Integer> requiredApprovalsByType = new HashMap<Integer, Integer>(); // Approval\r
+                                                                                         // countdown\r
+        Map<Integer, ApprovalType> approvalsByType = new HashMap<Integer, ApprovalType>(); // Just\r
+                                                                                           // for\r
+                                                                                           // logging\r
+\r
+        List<ApprovalType> approvalTypes = approvalTypeDAO.findByDomain(schedule.getDomain());\r
+        for (ApprovalType at : approvalTypes) {\r
+            Integer type = at.getId();\r
+            Integer count = at.getApprovalCount();\r
+            requiredApprovalsByType.put(type, count);\r
+            approvalsByType.put(at.getId(), at);\r
+        }\r
+\r
+        // Account for approvals so far\r
+        List<ScheduleApproval> existingApprovals = schedule.getScheduleApprovals();\r
+        if (existingApprovals == null) {\r
+            // This is necessary when doing automatic approvals because\r
+            // the schedule will not return the approvals here\r
+            existingApprovals = new ArrayList<ScheduleApproval>();\r
+            existingApprovals.add(sa);\r
+        }\r
+        for (ScheduleApproval approval : existingApprovals) {\r
+            if (approval.getStatus().equals(ApprovalStatusEnum.Accepted.toString())) {\r
+                Integer remaining = requiredApprovalsByType.get(approval.getApprovalTypeId());\r
+                if (remaining != null) {\r
+                    remaining = remaining - 1;\r
+                    requiredApprovalsByType.put(approval.getApprovalTypeId(), remaining);\r
+                } else {\r
+                    log.warn("Ignored Unidentified approval type {0} for domain {1}", approval.getApprovalTypeId(),\r
+                            schedule.getDomain());\r
+                }\r
+            }\r
+        }\r
+        for (Integer id : requiredApprovalsByType.keySet()) {\r
+            Integer remaining = requiredApprovalsByType.get(id);\r
+            if (remaining > 0) {\r
+                return false;\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSCallbackImpl.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSCallbackImpl.java
new file mode 100644 (file)
index 0000000..9fb8a96
--- /dev/null
@@ -0,0 +1,268 @@
+/*\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.service.rs;\r
+\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.transaction.Transactional;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.Response.Status;\r
+import javax.ws.rs.core.UriInfo;\r
+import org.joda.time.DateTime;\r
+import org.joda.time.format.DateTimeFormat;\r
+import org.joda.time.format.ISODateTimeFormat;\r
+import org.onap.optf.cmso.common.CMSStatusEnum;\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.exceptions.CMSException;\r
+import org.onap.optf.cmso.common.exceptions.CMSNotFoundException;\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.ChangeManagementChangeWindowDAO;\r
+import org.onap.optf.cmso.model.dao.ChangeManagementDetailDAO;\r
+import org.onap.optf.cmso.model.dao.ChangeManagementGroupDAO;\r
+import org.onap.optf.cmso.model.dao.ChangeManagementScheduleDAO;\r
+import org.onap.optf.cmso.optimizer.bean.CMOptimizerResponse;\r
+import org.onap.optf.cmso.optimizer.bean.CMSchedule;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.stereotype.Controller;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+\r
+@Controller\r
+public class CMSCallbackImpl extends BaseSchedulerServiceImpl implements CMSOptimizerCallback {\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(CMSCallbackImpl.class);\r
+    private static EELFLogger metrics = EELFManager.getInstance().getMetricsLogger();\r
+    private static EELFLogger audit = EELFManager.getInstance().getAuditLogger();\r
+    private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();\r
+    private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();\r
+\r
+    @Autowired\r
+    ChangeManagementScheduleDAO cmScheduleDAO;\r
+\r
+    @Autowired\r
+    ChangeManagementGroupDAO cmGroupDAO;\r
+\r
+    @Autowired\r
+    ChangeManagementChangeWindowDAO cmChangeWindowDAO;\r
+\r
+    @Autowired\r
+    ChangeManagementDetailDAO cmDetailsDAO;\r
+\r
+    @Override\r
+    @Transactional\r
+    public Response sniroCallback(String apiVersion, CMOptimizerResponse sniroResponse, UriInfo uri,\r
+            HttpServletRequest request) {\r
+        Response response = null;\r
+        Mdc.begin(request, sniroResponse.getTransactionId());\r
+        log.info(LogMessages.PROCESS_OPTIMIZER_CALLBACK, "Received", request.getRemoteAddr(), "");\r
+        log.info(LogMessages.OPTIMIZER_REQUEST, "Callback received", sniroResponse.getTransactionId(),\r
+                uri.getAbsolutePath().toString());\r
+        try {\r
+            // Note that transaction ID and schedule ID are currently the same value.\r
+\r
+            String transactionId = sniroResponse.getTransactionId();\r
+\r
+            // Synchronize this with transaction that scheduled the SNIRO optimization\r
+            // to ensure status updates are properly ordered.\r
+            // This is necessary only in the race condition where SNIRO callback comes\r
+            // before the SNIRO response is processed and the scheduling transaction is\r
+            // still in flight.\r
+            // Note that this may happen in loopback mode, but is not likely to happen with\r
+            // real SNIRO unless SNIRO changes to be synchronous and the callback comes before\r
+            // the response.\r
+            // If this lock times out, the schedule will remain in 'Optimization In\r
+            // Progress' and never complete.\r
+            Schedule schedule = scheduleDAO.lockOneByTransactionId(transactionId);\r
+\r
+            if (schedule == null) {\r
+                throw new CMSNotFoundException(DomainsEnum.ChangeManagement.toString(),\r
+                        "(OptimizerTransactionID=" + transactionId + ")");\r
+\r
+            }\r
+            CMSStatusEnum status = CMSStatusEnum.PendingApproval.fromString(schedule.getStatus());\r
+            debug.debug("Status at time of SNIRO callback is " + status.toString());\r
+            switch (status) {\r
+                // PendingSchedule may be a valid status in the cases where SNIRO async call\r
+                // returns before\r
+                // We have committed the OptimizationInProgress status\r
+                // The dispatch logic ensures that we only every dispatch once.\r
+                case OptimizationInProgress:\r
+                    processSniroResponse(sniroResponse, schedule);\r
+                    scheduleDAO.save(schedule);\r
+                    response = Response.ok().build();\r
+                    break;\r
+                default:\r
+                    throw new CMSException(Status.PRECONDITION_FAILED, LogMessages.OPTIMIZER_CALLBACK_STATE_ERROR,\r
+                            CMSStatusEnum.OptimizationInProgress.toString(), schedule.getStatus().toString());\r
+            }\r
+        } catch (CMSException e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            response = Response.serverError().entity(e.getMessage()).build();\r
+        } finally {\r
+        }\r
+        Mdc.end(response);\r
+        log.info(LogMessages.OPTIMIZER_REQUEST, "Callback completed", sniroResponse.getTransactionId(),\r
+                uri.getAbsolutePath().toString());\r
+        audit.info(LogMessages.PROCESS_OPTIMIZER_CALLBACK, "Returned", request.getRemoteAddr(),\r
+                response.getStatusInfo().toString());\r
+        metrics.info(LogMessages.PROCESS_OPTIMIZER_CALLBACK, "Returned", request.getRemoteAddr(),\r
+                response.getStatusInfo().toString());\r
+        return response;\r
+    }\r
+\r
+    private void processSniroResponse(CMOptimizerResponse sniroResponse, Schedule schedule) {\r
+        try {\r
+            schedule.setOptimizerReturnDateTimeMillis(System.currentTimeMillis());\r
+            schedule.setOptimizerStatus(sniroResponse.getRequestState());\r
+            schedule.setOptimizerMessage(sniroResponse.getDescription());\r
+            String scheduleId = sniroResponse.getScheduleId();\r
+            ObjectMapper om = new ObjectMapper();\r
+            CMSchedule[] scheduleArray = sniroResponse.getSchedule();\r
+            if (scheduleArray != null && scheduleArray.length > 0) {\r
+                String scheduleString = om.writeValueAsString(scheduleArray);\r
+                schedule.setSchedule(scheduleString);\r
+                log.debug("scheduleId={0} schedule={1}", scheduleId, scheduleString);\r
+                for (CMSchedule sniroSchedule : sniroResponse.getSchedule()) {\r
+                    String groupId = sniroSchedule.getGroupId();\r
+                    DateTime finishTime = convertDate(sniroSchedule.getFinishTime(), "finishTime");\r
+                    DateTime latestInstanceStartTime =\r
+                            convertDate(sniroSchedule.getLatestInstanceStartTime(), "latestInstanceStartTime");\r
+                    DateTime startTime = convertDate(sniroSchedule.getStartTime(), "startTime");\r
+                    ChangeManagementGroup group = cmGroupDAO.findOneBySchedulesIDGroupID(schedule.getId(), groupId);\r
+                    if (group == null) {\r
+                        throw new CMSException(Status.PRECONDITION_FAILED,\r
+                                LogMessages.CHANGE_MANAGEMENT_GROUP_NOT_FOUND, schedule.getScheduleId(), groupId);\r
+                    }\r
+                    group.setStartTimeMillis(startTime.getMillis());\r
+                    group.setFinishTimeMillis(finishTime.getMillis());\r
+                    group.setLastInstanceStartTimeMillis(latestInstanceStartTime.getMillis());\r
+                    cmGroupDAO.save(group);\r
+                    long totalDuration =\r
+                            (group.getAdditionalDurationInSecs() + group.getNormalDurationInSecs()) * 1000l;\r
+                    Map<String, Map<String, Long>> startAndFinishTimeMap = new HashMap<String, Map<String, Long>>();\r
+                    makeMap(startTime.getMillis(), latestInstanceStartTime.getMillis(), group.getConcurrencyLimit(),\r
+                            totalDuration, sniroSchedule.getNode(), startAndFinishTimeMap);\r
+                    for (String node : sniroSchedule.getNode()) {\r
+                        processNode(schedule, group, node, startAndFinishTimeMap);\r
+                    }\r
+                }\r
+                schedule.setStatus(CMSStatusEnum.PendingApproval.toString());\r
+            } else {\r
+                debug.debug("scheduleId={0} schedule=null status={1} ", scheduleId, schedule.getOptimizerStatus());\r
+                schedule.setStatus(CMSStatusEnum.OptimizationFailed.toString());\r
+            }\r
+        } catch (CMSException e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            schedule.setStatus(CMSStatusEnum.OptimizationFailed.toString());\r
+            schedule.setOptimizerStatus(e.getStatus().toString());\r
+            schedule.setOptimizerMessage(e.getLocalizedMessage());\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            schedule.setStatus(CMSStatusEnum.OptimizationFailed.toString());\r
+            schedule.setOptimizerStatus("Exception");\r
+            schedule.setOptimizerMessage(e.getLocalizedMessage());\r
+        }\r
+    }\r
+\r
+    public static void makeMap(Long startTime, Long latestInstanceStartTime, int concurrencyLimit, long totalDuration,\r
+            List<String> nodes, Map<String, Map<String, Long>> startAndFinishTimeMap) throws CMSException {\r
+        Long nextStartTime = null;\r
+        Long nextFinishTime = null;\r
+        for (int nodeNumber = 0; nodeNumber < nodes.size(); nodeNumber++) {\r
+            String node = nodes.get(nodeNumber);\r
+            if (nodeNumber % concurrencyLimit == 0) {\r
+                if (nodeNumber == 0)\r
+                    nextStartTime = startTime;\r
+                else\r
+                    nextStartTime = nextStartTime + totalDuration;\r
+                if (nextStartTime > latestInstanceStartTime) {\r
+                    throw new CMSException(Status.BAD_REQUEST, LogMessages.UNABLE_TO_ALLOCATE_VNF_TIMESLOTS,\r
+                            startTime.toString(), latestInstanceStartTime.toString(), String.valueOf(totalDuration),\r
+                            String.valueOf(concurrencyLimit), String.valueOf(nodes.size()));\r
+                }\r
+                nextFinishTime = nextStartTime + totalDuration;\r
+            }\r
+            Map<String, Long> map = new HashMap<String, Long>();\r
+            map.put("startTime", nextStartTime);\r
+            map.put("finishTime", nextFinishTime);\r
+            startAndFinishTimeMap.put(node, map);\r
+        }\r
+\r
+    }\r
+\r
+    private void processNode(Schedule schedule, ChangeManagementGroup group, String node,\r
+            Map<String, Map<String, Long>> startAndFinishTimeMap) throws CMSException {\r
+        Map<String, Long> map = startAndFinishTimeMap.get(node);\r
+        ChangeManagementSchedule detail = cmScheduleDAO.findOneByGroupIDAndVnfName(group.getId(), node);\r
+        if (detail == null) {\r
+            throw new CMSException(Status.NOT_FOUND, LogMessages.UNABLE_TO_LOCATE_SCHEDULE_DETAIL,\r
+                    schedule.getScheduleId(), group.getGroupId(), node);\r
+        }\r
+        detail.setStartTimeMillis(map.get("startTime"));\r
+        detail.setFinishTimeMillis(map.get("finishTime"));\r
+        detail.setVnfId("");\r
+        detail.setStatus(CMSStatusEnum.PendingApproval.toString());\r
+        cmScheduleDAO.save(detail);\r
+    }\r
+\r
+    public static DateTime convertDate(String utcDate, String attrName) throws CMSException {\r
+        try {\r
+            DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZoneUTC().parseDateTime(utcDate);\r
+            if (dateTime != null)\r
+                return dateTime;\r
+        } catch (Exception e) {\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+        }\r
+        throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_ATTRIBUTE, attrName, utcDate);\r
+    }\r
+\r
+    public static DateTime convertISODate(String utcDate, String attrName) throws CMSException {\r
+        try {\r
+            DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime(utcDate);\r
+            if (dateTime != null)\r
+                return dateTime;\r
+        } catch (Exception e) {\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+        }\r
+        throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_ATTRIBUTE, attrName, utcDate);\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOService.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOService.java
new file mode 100644 (file)
index 0000000..97bb78e
--- /dev/null
@@ -0,0 +1,206 @@
+/*\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.service.rs;\r
+\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.ws.rs.DELETE;\r
+import javax.ws.rs.DefaultValue;\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.POST;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.QueryParam;\r
+import javax.ws.rs.core.Context;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.UriInfo;\r
+import org.onap.optf.cmso.common.CMSRequestError;\r
+import org.onap.optf.cmso.model.Schedule;\r
+import org.onap.optf.cmso.service.rs.models.ApprovalMessage;\r
+import org.onap.optf.cmso.service.rs.models.CMSMessage;\r
+import org.onap.optf.cmso.service.rs.models.CmDetailsMessage;\r
+import io.swagger.annotations.Api;\r
+import io.swagger.annotations.ApiOperation;\r
+import io.swagger.annotations.ApiParam;\r
+import io.swagger.annotations.ApiResponse;\r
+import io.swagger.annotations.ApiResponses;\r
+\r
+@Api\r
+@Path("/{apiVersion}")\r
+@Produces({MediaType.APPLICATION_JSON})\r
+public interface CMSOService {\r
+    // ******************************************************************\r
+    @GET\r
+    @Path("/schedules")\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "", notes = "Returns a list of Scheduler Requests based upon the filter criteria.",\r
+            response = Schedule.class, responseContainer = "List")\r
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"),\r
+            @ApiResponse(code = 404, message = "No records found", response = CMSRequestError.class),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)})\r
+    public Response searchScheduleRequests(\r
+            @ApiParam(value = "v1") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @DefaultValue(value = "false") @ApiParam(\r
+                    value = "Include details") @QueryParam("includeDetails") Boolean includeDetails,\r
+            @ApiParam(value = "Schedule identifier", allowMultiple = true) @QueryParam("scheduleId") String scheduleId,\r
+            @ApiParam(value = "Schedule name", allowMultiple = true) @QueryParam("scheduleName") String scheduleName,\r
+            @ApiParam(value = "SCheduler creator User id of ",\r
+                    allowMultiple = true) @QueryParam("userId") String userId,\r
+            @ApiParam(value = "Schedule status", allowMultiple = true) @QueryParam("status") String status,\r
+            @ApiParam(value = "Creation date and time (<low date>[,<hi date>])",\r
+                    allowMultiple = true) @QueryParam("createDateTime") String createDateTime,\r
+            @ApiParam(value = "Optimizer status",\r
+                    allowMultiple = true) @QueryParam("optimizerStatus") String optimizerStatus,\r
+            @ApiParam(value = "Workflow", allowMultiple = true) @QueryParam("WorkflowName") String workflowName,\r
+            @Context UriInfo uri, @Context HttpServletRequest request);\r
+\r
+    // ******************************************************************\r
+    @POST\r
+    @Path("/schedules/{scheduleId}")\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "", notes = "Creates a schedule request for scheduleId")\r
+    @ApiResponses(\r
+            value = {@ApiResponse(code = 202, message = "Schedule request accepted for optimization."),\r
+                    @ApiResponse(code = 409, message = "Schedule request already exists for this schedule id.",\r
+                            response = CMSRequestError.class),\r
+                    @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    public Response createScheduleRequest(\r
+            @ApiParam(value = "v1") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @ApiParam(\r
+                    value = "Schedule id to uniquely identify the schedule request being created.") @PathParam("scheduleId") String scheduleId,\r
+            @ApiParam(\r
+                    value = "Data for creating a schedule request for the given schedule id") CMSMessage scheduleMessage,\r
+            @Context HttpServletRequest request);\r
+\r
+    // ******************************************************************\r
+    @DELETE\r
+    @Path("/schedules/{scheduleId}")\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "", notes = "Cancels the schedule request for scheduleId")\r
+    @ApiResponses(value = {@ApiResponse(code = 204, message = "Delete successful"),\r
+            @ApiResponse(code = 404, message = "No record found", response = CMSRequestError.class),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    public Response deleteScheduleRequest(\r
+            @ApiParam(value = "v1") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @ApiParam(\r
+                    value = "Schedule id to uniquely identify the schedule request being deleted.") @PathParam("scheduleId") String scheduleId,\r
+            @Context HttpServletRequest request);\r
+\r
+    // ******************************************************************\r
+    @GET\r
+    @Path("/schedules/{scheduleId}")\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "", notes = "Retrieve the schedule request for scheduleId", response = Schedule.class)\r
+    @ApiResponses(\r
+            value = {@ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 404, message = "No record found"),\r
+                    @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    public Response getScheduleRequestInfo(\r
+            @ApiParam(value = "v1") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @ApiParam(\r
+                    value = "Schedule id to uniquely identify the schedule info being retrieved.") @PathParam("scheduleId") String scheduleId,\r
+            @Context HttpServletRequest request);\r
+\r
+    // ******************************************************************\r
+    @POST\r
+    @Path("/schedules/{scheduleId}/approvals")\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "",\r
+            notes = "Adds an accept/reject approval status to the schedule request identified by scheduleId")\r
+    @ApiResponses(\r
+            value = {@ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 404, message = "No record found"),\r
+                    @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    public Response approveScheduleRequest(\r
+            @ApiParam(value = "v1") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @ApiParam(\r
+                    value = "Schedule id to uniquely identify the schedule request being accepted or rejected.") @PathParam("scheduleId") String scheduleId,\r
+            @ApiParam(value = "Accept or reject approval message") ApprovalMessage approval,\r
+            @Context HttpServletRequest request);\r
+\r
+    // ******************************************************************\r
+    @GET\r
+    @Path("/schedules/scheduleDetails")\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "", notes = "Returns a list of Schedule request details based upon the filter criteria.",\r
+            response = CmDetailsMessage.class, responseContainer = "List")\r
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"),\r
+            @ApiResponse(code = 404, message = "No records found", response = CMSRequestError.class),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)})\r
+    public Response searchScheduleRequestDetails(\r
+            @ApiParam(value = "v1") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @ApiParam(value = "Schedule identifier",\r
+                    allowMultiple = true) @QueryParam("request.scheduleId") String scheduleId,\r
+            @ApiParam(value = "Schedule name",\r
+                    allowMultiple = true) @QueryParam("request.scheduleName") String scheduleName,\r
+            @ApiParam(value = "Scheduler creator User id of ",\r
+                    allowMultiple = true) @QueryParam("request.userId") String userId,\r
+            @ApiParam(value = "Schedule status", allowMultiple = true) @QueryParam("request.status") String status,\r
+            @ApiParam(value = "Creation date and time (<low date>[,<hi date>])",\r
+                    allowMultiple = true) @QueryParam("request.createDateTime") String createDateTime,\r
+            @ApiParam(value = "Optimizer status",\r
+                    allowMultiple = true) @QueryParam("request.optimizerStatus") String optimizerStatus,\r
+            @ApiParam(value = "Request Approval user id",\r
+                    allowMultiple = true) @QueryParam("request.approvalUserId") String requestApprovalUserId,\r
+            @ApiParam(value = "Request Approval status",\r
+                    allowMultiple = true) @QueryParam("request.approvalStatus") String requestApprovalStatus,\r
+            @ApiParam(value = "Request Approval type",\r
+                    allowMultiple = true) @QueryParam("request.approvalType") String requestApprovalType,\r
+            @ApiParam(value = "Workflow", allowMultiple = true) @QueryParam("WorkflowName") String workflowName,\r
+            @ApiParam(value = "VNF Name", allowMultiple = true) @QueryParam("vnfName") String vnfName,\r
+            @ApiParam(value = "VNF Id", allowMultiple = true) @QueryParam("vnfId") String vnfId,\r
+            @ApiParam(value = "VNF Status", allowMultiple = true) @QueryParam("vnfStatus") String vnfStatus,\r
+            // @ApiParam(value="VNF Schedule Id", allowMultiple=true) @QueryParam("vnfScheduleId")\r
+            // String\r
+            // vnfScheduleId,\r
+            @ApiParam(value = "Start time <low>,<high>",\r
+                    allowMultiple = true) @QueryParam("startTime") String startTime,\r
+            @ApiParam(value = "Finish time <low>,<high>",\r
+                    allowMultiple = true) @QueryParam("finishTime") String finishTime,\r
+            @ApiParam(value = "Last instance start time <low>,<high>",\r
+                    allowMultiple = true) @QueryParam("lastInstanceTime") String lastInstanceTime,\r
+            @ApiParam(value = "TM Change Ticket Change Id",\r
+                    allowMultiple = true) @QueryParam("tmChangeId") String tmChangeId,\r
+            // @ApiParam(value="Approval user id", allowMultiple=true) @QueryParam("approvalUserId")\r
+            // String approvalUserId,\r
+            // @ApiParam(value="Approval status", allowMultiple=true) @QueryParam("approvalStatus")\r
+            // String\r
+            // approvalStatus,\r
+            // @ApiParam(value="Approval type", allowMultiple=true) @QueryParam("approvalType")\r
+            // String\r
+            // approvalType,\r
+            @ApiParam(value = "Maximum number of schedules to return") @QueryParam("maxSchedules") Integer maxSchedules,\r
+            @ApiParam(value = "Return schedules > lastScheduleId") @QueryParam("lastScheduleId") String lastScheduleId,\r
+            @ApiParam(\r
+                    value = "Return concurrencyLimit") @QueryParam("request.concurrencyLimit") Integer concurrencyLimit,\r
+            @Context UriInfo uri, @Context HttpServletRequest request);\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOServiceImpl.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOServiceImpl.java
new file mode 100644 (file)
index 0000000..26d0fe5
--- /dev/null
@@ -0,0 +1,743 @@
+/*\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.service.rs;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.TimeZone;\r
+import java.util.UUID;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.ws.rs.core.MultivaluedMap;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.Response.Status;\r
+import javax.ws.rs.core.UriInfo;\r
+import org.joda.time.DateTime;\r
+import org.onap.optf.cmso.common.ApprovalStatusEnum;\r
+import org.onap.optf.cmso.common.ApprovalTypesEnum;\r
+import org.onap.optf.cmso.common.CMSStatusEnum;\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.exceptions.CMSException;\r
+import org.onap.optf.cmso.common.exceptions.CMSNotFoundException;\r
+import org.onap.optf.cmso.eventq.CMSQueueJob;\r
+import org.onap.optf.cmso.model.ChangeManagementChangeWindow;\r
+import org.onap.optf.cmso.model.ChangeManagementDetail;\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.ScheduleQuery;\r
+import org.onap.optf.cmso.model.dao.ChangeManagementChangeWindowDAO;\r
+import org.onap.optf.cmso.model.dao.ChangeManagementDetailDAO;\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.model.dao.ScheduleQueryDAO;\r
+import org.onap.optf.cmso.service.rs.models.ApprovalMessage;\r
+import org.onap.optf.cmso.service.rs.models.CMSInfo;\r
+import org.onap.optf.cmso.service.rs.models.CMSMessage;\r
+import org.onap.optf.cmso.service.rs.models.ChangeWindowMessage;\r
+import org.onap.optf.cmso.service.rs.models.CmDetailsMessage;\r
+import org.onap.optf.cmso.service.rs.models.CmDomainDataEnum;\r
+import org.onap.optf.cmso.service.rs.models.VnfDetailsMessage;\r
+import org.onap.optf.cmso.ticketmgt.TmClient;\r
+import org.onap.optf.cmso.ticketmgt.bean.BuildCreateRequest;\r
+import org.onap.optf.cmso.ticketmgt.bean.TmApprovalStatusEnum;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.stereotype.Controller;\r
+import org.springframework.transaction.annotation.Transactional;\r
+import org.springframework.transaction.interceptor.TransactionAspectSupport;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+\r
+@Controller\r
+public class CMSOServiceImpl extends BaseSchedulerServiceImpl implements CMSOService {\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(CMSOServiceImpl.class);\r
+    private static EELFLogger metrics = EELFManager.getInstance().getMetricsLogger();\r
+    private static EELFLogger audit = EELFManager.getInstance().getAuditLogger();\r
+    private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();\r
+    private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();\r
+\r
+    @Autowired\r
+    CMSQueueJob qJob;\r
+\r
+    @Autowired\r
+    Environment env;\r
+\r
+    @Autowired\r
+    ChangeManagementScheduleDAO cmScheduleDAO;\r
+\r
+    @Autowired\r
+    ChangeManagementGroupDAO cmGroupDAO;\r
+\r
+    @Autowired\r
+    ChangeManagementChangeWindowDAO cmChangeWindowDAO;\r
+\r
+    @Autowired\r
+    ChangeManagementDetailDAO cmDetailsDAO;\r
+\r
+    @Autowired\r
+    ScheduleQueryDAO scheduleQueryDAO;\r
+\r
+    @Autowired\r
+    ScheduleDAO scheduleDAO;\r
+\r
+    @Autowired\r
+    TmClient tmClient;\r
+\r
+    @Autowired\r
+    BuildCreateRequest buildCreateRequest;\r
+\r
+    @Override\r
+    public Response searchScheduleRequests(String apiVersion, Boolean includeDetails, String scheduleId,\r
+            String scheduleName, String userId, String status, String createDateTime, String optimizerStatus,\r
+            String workflowName, UriInfo uri, HttpServletRequest request) {\r
+\r
+        Mdc.begin(request, UUID.randomUUID().toString());\r
+        log.info(LogMessages.SEARCH_SCHEDULE_REQUEST, "Received", request.getRemoteAddr(), uri.toString(), "");\r
+        Response response = null;\r
+        List<Schedule> schedules = new ArrayList<Schedule>();\r
+        try {\r
+            log.info("Timezone=" + TimeZone.getDefault());\r
+            MultivaluedMap<String, String> qp = uri.getQueryParameters();\r
+            StringBuilder where = new StringBuilder();\r
+            int maxRows = 0;\r
+            // buildWhere(qp, where);\r
+            List<ScheduleQuery> list = scheduleQueryDAO.searchSchedules(where.toString(), maxRows);\r
+            if (list == null || !list.iterator().hasNext()) {\r
+                throw new CMSException(Status.NOT_FOUND, LogMessages.SCHEDULE_NOT_FOUND,\r
+                        DomainsEnum.ChangeManagement.toString(), scheduleId);\r
+            }\r
+            Iterator<ScheduleQuery> iter = list.iterator();\r
+            while (iter.hasNext()) {\r
+                Schedule s = scheduleDAO.findById(iter.next().getId()).orElse(null);\r
+                if (s != null) {\r
+                    schedules.add(s);\r
+                    if (includeDetails) {\r
+                        List<ChangeManagementGroup> groups = cmGroupDAO.findBySchedulesID(s.getId());\r
+                        s.setGroups(groups);\r
+                        for (ChangeManagementGroup g : groups) {\r
+                            List<ChangeManagementSchedule> cmSchedules =\r
+                                    cmScheduleDAO.findByChangeManagementGroupId(g.getId());\r
+                            g.setChangeManagementSchedules(cmSchedules);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            response = Response.ok(schedules.toArray(new Schedule[schedules.size()])).build();\r
+        } catch (CMSException e) {\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            log.info(e.getMessage());\r
+            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            response = Response.serverError().build();\r
+        }\r
+\r
+        Mdc.end(response);\r
+        log.info(LogMessages.SEARCH_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), schedules.toString(),\r
+                response.getStatusInfo().toString());\r
+        audit.info(LogMessages.SEARCH_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), schedules.toString(),\r
+                response.getStatusInfo().toString());\r
+        metrics.info(LogMessages.SEARCH_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), schedules.toString(),\r
+                response.getStatusInfo().toString());\r
+        return response;\r
+    }\r
+\r
+    @Override\r
+    @Transactional\r
+    public Response createScheduleRequest(String apiVersion, String scheduleId, CMSMessage scheduleMessage,\r
+            HttpServletRequest request) {\r
+        Mdc.begin(request, scheduleId);\r
+        log.info(LogMessages.CREATE_SCHEDULE_REQUEST, "Received", request.getRemoteAddr(), scheduleId,\r
+                scheduleMessage.toString());\r
+        Response response = null;\r
+        try {\r
+            if (!scheduleMessage.getDomain().equals(DomainsEnum.ChangeManagement.toString())) {\r
+                throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_ATTRIBUTE, "domain",\r
+                        scheduleMessage.getDomain());\r
+            }\r
+            if (scheduleMessage.getScheduleId() == null || !scheduleMessage.getScheduleId().equals(scheduleId)) {\r
+                throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_ATTRIBUTE, "schedulerId",\r
+                        scheduleMessage.getScheduleId());\r
+            }\r
+            // Force the name to be = to the ID because there is no way fot the provide a\r
+            // name\r
+            scheduleMessage.setScheduleName(scheduleMessage.getScheduleId());\r
+\r
+            List<DomainData> domainData = validateDomainData(scheduleMessage);\r
+            boolean immediate = validate(scheduleMessage);\r
+            Schedule schedule = validateAndAddScheduleRequest(scheduleMessage, domainData);\r
+            if (immediate) {\r
+                createChangeManagementImmediate(schedule, scheduleMessage);\r
+\r
+                // *******************************************************************************************\r
+                // This flush does nothing because JPA is expecting\r
+                // JtaTransactionCoordinatorImpl\r
+                // rather than\r
+                // JdbcResourceLocalTransactionCoordinatorImpl\r
+                // (it does an instance of and JdbcResourceLocalTransactionCoordinatorImpl\r
+                // fails)\r
+                // SO the automatic approval and creation of tickets cannot\r
+                // rely retrieving the entities from the Schedule entity as the SQL has not yet\r
+                // executed.\r
+                // Under future flow, they can because the data is committed in a separate\r
+                // transaction\r
+                // Three choices\r
+                // 1. Pass domainData through all of the methods. ***\r
+                // 2. Re-structre the code to have @Transactionals which would break the top\r
+                // level rollback strategy\r
+                // 3. Debug JPA (Still worth doing, maybe some kind of goofy parameter.)\r
+                TransactionAspectSupport.currentTransactionStatus().flush();\r
+\r
+                // Create automatic approval\r
+                ApprovalMessage am = new ApprovalMessage();\r
+                am.setApprovalStatus(ApprovalStatusEnum.Accepted);\r
+                am.setApprovalType(ApprovalTypesEnum.Tier2);\r
+                am.setApprovalUserId(schedule.getUserId());\r
+                processApproveScheduleRequest(schedule, am, domainData);\r
+\r
+            } else {\r
+                createChangeManagement(schedule, scheduleMessage);\r
+            }\r
+            response = Response.accepted().build();\r
+        } catch (CMSException e) {\r
+            debug.debug(LogMessages.EXPECTED_EXCEPTION, e, e.getMessage());\r
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();\r
+            log.info(e.getMessage());\r
+            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();\r
+            Mdc.end(response);\r
+            audit.info(LogMessages.CREATE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId, "");\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();\r
+            response = Response.serverError().build();\r
+            Mdc.end(response);\r
+            audit.info(LogMessages.CREATE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId, "");\r
+        }\r
+        Mdc.end(response);\r
+        log.info(LogMessages.CREATE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        audit.info(LogMessages.CREATE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        metrics.info(LogMessages.CREATE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        return response;\r
+    }\r
+\r
+    /**\r
+     * Returns whether this is an immediate request\r
+     */\r
+    private boolean validate(CMSMessage scheduleMessage) throws CMSException {\r
+        Set<String> groups = new HashSet<String>();\r
+        CMSInfo info = scheduleMessage.getSchedulingInfo();\r
+        if (info == null) {\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.UNABLE_TO_PARSE_SCHEDULING_INFO);\r
+        }\r
+\r
+        if (scheduleMessage.getSchedulingInfo().getAdditionalDurationInSeconds() == null)\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE,\r
+                    "additionalDurationInSeconds");\r
+        if (scheduleMessage.getSchedulingInfo().getNormalDurationInSeconds() == null)\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE,\r
+                    "normalDurationInSeconds");\r
+        if (scheduleMessage.getSchedulingInfo().getAdditionalDurationInSeconds() < 0)\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_ATTRIBUTE, "additionalDurationInSeconds",\r
+                    scheduleMessage.getSchedulingInfo().getAdditionalDurationInSeconds().toString());\r
+        if (scheduleMessage.getSchedulingInfo().getNormalDurationInSeconds() < 1)\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_ATTRIBUTE, "normalDurationInSeconds",\r
+                    scheduleMessage.getSchedulingInfo().getNormalDurationInSeconds().toString());\r
+        try {\r
+            for (VnfDetailsMessage vnfDetail : scheduleMessage.getSchedulingInfo().getVnfDetails()) {\r
+                if (vnfDetail.getChangeWindow() != null && vnfDetail.getChangeWindow().size() > 0) {\r
+                    if (vnfDetail.getNode().size() == 0) {\r
+                        throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE, "node list");\r
+                    }\r
+                    for (String node : vnfDetail.getNode()) {\r
+                        if (node.equals(""))\r
+                            throw new CMSException(Status.BAD_REQUEST, LogMessages.NODE_LIST_CONTAINS_EMTPY_NODE);\r
+                    }\r
+                    for (ChangeWindowMessage cw : vnfDetail.getChangeWindow()) {\r
+                        if (cw.getStartTime() == null || cw.getStartTime().equals(""))\r
+                            throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE,\r
+                                    "startTime");\r
+                        if (cw.getEndTime() == null || cw.getEndTime().equals(""))\r
+                            throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE,\r
+                                    "endTime");\r
+                        DateTime start = CMSCallbackImpl.convertISODate(cw.getStartTime(), "startTime");\r
+                        DateTime end = CMSCallbackImpl.convertISODate(cw.getEndTime(), "endTime");\r
+                        if (!end.isAfter(start))\r
+                            throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_CHANGE_WINDOW,\r
+                                    cw.getStartTime(), cw.getEndTime());\r
+                    }\r
+                    if (scheduleMessage.getSchedulingInfo().getConcurrencyLimit() == null)\r
+                        throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE,\r
+                                "concurrencyLimit");\r
+                    if (scheduleMessage.getSchedulingInfo().getConcurrencyLimit() < 1)\r
+                        throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_ATTRIBUTE, "concurrencyLimit",\r
+                                scheduleMessage.getSchedulingInfo().getConcurrencyLimit().toString());\r
+                    if (scheduleMessage.getSchedulingInfo().getPolicyId() == null\r
+                            || scheduleMessage.getSchedulingInfo().getPolicyId().equals(""))\r
+                        throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE, "policyId");\r
+                    return false;\r
+                }\r
+                if (vnfDetail.getGroupId() == null || vnfDetail.getGroupId().equals(""))\r
+                    groups.add("default");\r
+                else\r
+                    groups.add(vnfDetail.getGroupId());\r
+            }\r
+        } catch (CMSException e) {\r
+            throw e;\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            throw new CMSException(Status.INTERNAL_SERVER_ERROR, LogMessages.UNEXPECTED_EXCEPTION, e.getMessage());\r
+        }\r
+        // If we got here, there are no change windows....\r
+        if (groups.size() > 1)\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.MULTIPLE_GROUPS_NOT_SUPPORTED);\r
+        return true;\r
+\r
+    }\r
+\r
+    private void createChangeManagement(Schedule schedule, CMSMessage scheduleMessage) throws CMSException {\r
+        CMSInfo schedulingInfo = scheduleMessage.getSchedulingInfo();\r
+        for (VnfDetailsMessage vnfDetail : schedulingInfo.getVnfDetails()) {\r
+            ChangeManagementGroup cmg = new ChangeManagementGroup();\r
+            cmg.setSchedulesId(schedule.getId());\r
+            cmg.setGroupId("");\r
+            if (vnfDetail.getGroupId() != null)\r
+                cmg.setGroupId(vnfDetail.getGroupId());\r
+            cmg.setPolicyId(schedulingInfo.getPolicyId());\r
+            cmg.setNormalDurationInSecs(schedulingInfo.getNormalDurationInSeconds());\r
+            cmg.setAdditionalDurationInSecs(schedulingInfo.getAdditionalDurationInSeconds());\r
+            cmg.setConcurrencyLimit(schedulingInfo.getConcurrencyLimit());\r
+            cmGroupDAO.save(cmg);\r
+            for (ChangeWindowMessage cw : vnfDetail.getChangeWindow()) {\r
+                ChangeManagementChangeWindow cmcw = new ChangeManagementChangeWindow();\r
+                cmcw.setChangeManagementGroupsId(cmg.getId());\r
+                DateTime start = CMSCallbackImpl.convertISODate(cw.getStartTime(), "startTime");\r
+                DateTime end = CMSCallbackImpl.convertISODate(cw.getEndTime(), "startTime");\r
+                cmcw.setStartTimeMillis(start.getMillis());\r
+                cmcw.setFinishTimeMillis(end.getMillis());\r
+                cmChangeWindowDAO.save(cmcw);\r
+            }\r
+\r
+            for (String vnf : vnfDetail.getNode()) {\r
+                ChangeManagementSchedule cms = new ChangeManagementSchedule();\r
+                cms.setChangeManagementGroupsId(cmg.getId());\r
+                cms.setVnfName(vnf);\r
+                cms.setStatus(CMSStatusEnum.PendingSchedule.toString());\r
+                cmScheduleDAO.save(cms);\r
+            }\r
+        }\r
+    }\r
+\r
+    private void createChangeManagementImmediate(Schedule schedule, CMSMessage scheduleMessage) throws CMSException {\r
+        CMSInfo schedulingInfo = scheduleMessage.getSchedulingInfo();\r
+        for (VnfDetailsMessage vnfDetail : schedulingInfo.getVnfDetails()) {\r
+            ChangeManagementGroup cmg = new ChangeManagementGroup();\r
+            cmg.setSchedulesId(schedule.getId());\r
+            cmg.setGroupId("");\r
+            int duration = schedulingInfo.getNormalDurationInSeconds();\r
+            int backout = schedulingInfo.getAdditionalDurationInSeconds();\r
+            cmg.setStartTimeMillis(System.currentTimeMillis());\r
+            cmg.setFinishTimeMillis(System.currentTimeMillis() + ((duration * 1000) + (backout * 1000)));\r
+            cmg.setNormalDurationInSecs(duration);\r
+            cmg.setAdditionalDurationInSecs(backout);\r
+            if (vnfDetail.getGroupId() != null)\r
+                cmg.setGroupId(vnfDetail.getGroupId());\r
+            cmGroupDAO.save(cmg);\r
+            for (String vnf : vnfDetail.getNode()) {\r
+                ChangeManagementSchedule cms = new ChangeManagementSchedule();\r
+                cms.setChangeManagementGroupsId(cmg.getId());\r
+                cms.setVnfName(vnf);\r
+                cms.setStatus(CMSStatusEnum.PendingApproval.toString());\r
+                cmScheduleDAO.save(cms);\r
+            }\r
+            schedule.setStatus(CMSStatusEnum.PendingApproval.toString());\r
+        }\r
+    }\r
+\r
+    private void deleteChangeManagement(Schedule schedule) throws CMSException {\r
+        List<ChangeManagementGroup> cmgs = cmGroupDAO.findBySchedulesID(schedule.getId());\r
+\r
+        for (ChangeManagementGroup cmg : cmgs) {\r
+            List<ChangeManagementSchedule> schedules = cmScheduleDAO.findByChangeManagementGroupId(cmg.getId());\r
+            for (ChangeManagementSchedule s : schedules) {\r
+                CMSStatusEnum currentState = CMSStatusEnum.Completed.fromString(s.getStatus());\r
+                switch (currentState) {\r
+                    case Scheduled:\r
+                        if (s.getTmChangeId() != null && !s.getTmChangeId().equals(""))\r
+                            tmClient.cancelTicket(schedule, s, s.getTmChangeId());\r
+                        s.setStatus(CMSStatusEnum.Cancelled.toString());\r
+                        break;\r
+                    case Triggered:\r
+                        // Too late...\r
+                        break;\r
+                    default:\r
+                        s.setStatus(CMSStatusEnum.Deleted.toString());\r
+                }\r
+                cmScheduleDAO.save(s);\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    private List<DomainData> validateDomainData(CMSMessage scheduleMessage) throws CMSException {\r
+        List<Map<String, String>> domainData = scheduleMessage.getDomainData();\r
+        List<DomainData> domainDataList = new ArrayList<DomainData>();\r
+        Set<String> requiredFields = new HashSet<String>();\r
+        for (CmDomainDataEnum req : CmDomainDataEnum.values()) {\r
+            if (req.isRequired())\r
+                requiredFields.add(req.name());\r
+        }\r
+        for (Map<String, String> nameValue : domainData) {\r
+            for (String name : nameValue.keySet()) {\r
+                String value = nameValue.get(name);\r
+                // Save for later validation\r
+                DomainData dd = new DomainData();\r
+                dd.setName(name);\r
+                dd.setValue(value);\r
+                domainDataList.add(dd);\r
+                requiredFields.remove(name);\r
+                try {\r
+                    CmDomainDataEnum.valueOf(name);\r
+                } catch (Exception e) {\r
+                    log.warn(LogMessages.UNDEFINED_DOMAIN_DATA_ATTRIBUTE, DomainsEnum.ChangeManagement.name(), name,\r
+                            value);\r
+                }\r
+            }\r
+        }\r
+        if (requiredFields.size() > 0) {\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE,\r
+                    requiredFields.toString());\r
+        }\r
+        return domainDataList;\r
+\r
+    }\r
+\r
+    @Override\r
+    @Transactional\r
+    public Response deleteScheduleRequest(String apiVersion, String scheduleId, HttpServletRequest request) {\r
+        Mdc.begin(request, scheduleId);\r
+        Response response = null;\r
+        log.info(LogMessages.DELETE_SCHEDULE_REQUEST, "Received", request.getRemoteAddr(), scheduleId, "");\r
+        try {\r
+            Schedule schedule = scheduleDAO.findByDomainScheduleID(DomainsEnum.ChangeManagement.toString(), scheduleId);\r
+            if (schedule == null) {\r
+                throw new CMSNotFoundException(DomainsEnum.ChangeManagement.toString(), scheduleId);\r
+            }\r
+            deleteChangeManagement(schedule);\r
+            deleteScheduleRequest(DomainsEnum.ChangeManagement.toString(), scheduleId);\r
+            response = Response.noContent().build();\r
+        } catch (CMSException e) {\r
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();\r
+            log.info(e.getMessage());\r
+            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();\r
+            response = Response.serverError().build();\r
+        }\r
+        Mdc.end(response);\r
+        log.info(LogMessages.DELETE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        audit.info(LogMessages.DELETE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        metrics.info(LogMessages.DELETE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        return response;\r
+    }\r
+\r
+    @Override\r
+    public Response getScheduleRequestInfo(String apiVersion, String scheduleId, HttpServletRequest request) {\r
+        Response response = null;\r
+        Mdc.begin(request, scheduleId);\r
+        log.info(LogMessages.GET_SCHEDULE_REQUEST_INFO, "Received", request.getRemoteAddr(), scheduleId, "");\r
+        Schedule schedule = null;\r
+        try {\r
+            schedule = scheduleDAO.findByDomainScheduleID(DomainsEnum.ChangeManagement.toString(), scheduleId);\r
+            if (schedule == null) {\r
+                throw new CMSException(Status.NOT_FOUND, LogMessages.SCHEDULE_NOT_FOUND,\r
+                        DomainsEnum.ChangeManagement.toString(), scheduleId);\r
+            }\r
+            response = Response.ok().entity(schedule).build();\r
+        } catch (CMSException e) {\r
+            log.info(e.getMessage());\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            response = Response.serverError().build();\r
+        }\r
+        Mdc.end(response);\r
+        audit.info(LogMessages.GET_SCHEDULE_REQUEST_INFO, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        metrics.info(LogMessages.GET_SCHEDULE_REQUEST_INFO, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        log.info(LogMessages.GET_SCHEDULE_REQUEST_INFO, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        return response;\r
+    }\r
+\r
+    @Override\r
+    @Transactional\r
+    public Response approveScheduleRequest(String apiVersion, String scheduleId, ApprovalMessage approval,\r
+            HttpServletRequest request) {\r
+        Response response = null;\r
+        Mdc.begin(request, scheduleId);\r
+        log.info(LogMessages.APPROVE_SCHEDULE_REQUEST, "Received", request.getRemoteAddr(), scheduleId,\r
+                approval.toString());\r
+        try {\r
+            String domain = DomainsEnum.ChangeManagement.toString();\r
+            Schedule s = scheduleDAO.findByDomainScheduleID(domain, scheduleId);\r
+            if (s == null) {\r
+                throw new CMSNotFoundException(domain, scheduleId);\r
+            }\r
+            processApproveScheduleRequest(s, approval, s.getDomainData());\r
+            response = Response.noContent().build();\r
+        } catch (CMSException e) {\r
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();\r
+            log.info(e.getMessage());\r
+            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();\r
+            response = Response.serverError().build();\r
+        }\r
+        Mdc.end(response);\r
+        log.info(LogMessages.APPROVE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId, "");\r
+        audit.info(LogMessages.APPROVE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        metrics.info(LogMessages.APPROVE_SCHEDULE_REQUEST, "Returned", request.getRemoteAddr(), scheduleId,\r
+                response.getStatusInfo().toString());\r
+        return response;\r
+    }\r
+\r
+    private void processApproveScheduleRequest(Schedule s, ApprovalMessage approval, List<DomainData> domainData)\r
+            throws CMSException {\r
+        s = scheduleDAO.lockOne(s.getId());\r
+        String domain = DomainsEnum.ChangeManagement.toString();\r
+        processApproval(s, domain, approval);\r
+        if (s.getStatus().equals(CMSStatusEnum.Accepted.toString())) {\r
+            openTickets(s, domainData);\r
+        }\r
+        if (s.getStatus().equals(CMSStatusEnum.Rejected.toString())) {\r
+            updateChangeManagementSchedules(s, CMSStatusEnum.ApprovalRejected);\r
+        }\r
+    }\r
+\r
+    private void openTickets(Schedule s, List<DomainData> domainData) throws CMSException {\r
+        debug.debug("Entered openTickets scheduleId=" + s.getScheduleId());\r
+\r
+        Integer max_vnfs_per_ticket = env.getProperty("tm.vnfs.per.ticket", Integer.class, 1);\r
+\r
+        List<ChangeManagementGroup> groups = cmGroupDAO.findBySchedulesID(s.getId());\r
+        for (ChangeManagementGroup group : groups) {\r
+\r
+            List<ChangeManagementSchedule> schedules = cmScheduleDAO.findByChangeManagementGroupId(group.getId());\r
+            List<List<ChangeManagementSchedule>> ticketList = new ArrayList<List<ChangeManagementSchedule>>();\r
+            List<ChangeManagementSchedule> current = null;\r
+            for (ChangeManagementSchedule cms : schedules) {\r
+                if (current == null || current.size() == max_vnfs_per_ticket) {\r
+                    current = new ArrayList<ChangeManagementSchedule>();\r
+                    ticketList.add(current);\r
+                }\r
+                current.add(cms);\r
+            }\r
+            for (List<ChangeManagementSchedule> list : ticketList) {\r
+                openTicketForList(s, group, list, domainData);\r
+            }\r
+        }\r
+        debug.debug("Exited openTickets scheduleId=" + s.getScheduleId());\r
+    }\r
+\r
+    private void openTicketForList(Schedule schedule, ChangeManagementGroup group, List<ChangeManagementSchedule> list,\r
+            List<DomainData> domainData) throws CMSException {\r
+        List<String> vnfNames = new ArrayList<>();\r
+        for (ChangeManagementSchedule cms : list) {\r
+            vnfNames.add(cms.getVnfName());\r
+        }\r
+\r
+        debug.debug(\r
+                "Calling createChangeTicket scheduleId=" + schedule.getScheduleId() + ", group=" + group.getGroupId(),\r
+                ", vnfNames=" + vnfNames);\r
+        String changeId = tmClient.createChangeTicket(schedule, group, vnfNames, domainData);\r
+\r
+        // Pre-approve the ticket\r
+        for (ChangeManagementSchedule cms : list) {\r
+            cms.getTmApprovalStatus();\r
+            cms.setTmChangeId(changeId);\r
+            cms.setTmApprovalStatus(TmApprovalStatusEnum.Approved.toString());\r
+            // cms.setStatus(CMSStatusEnum.PendingApproval.toString());\r
+            if (cms.getStartTimeMillis() == null)\r
+                cms.setStatus(CMSStatusEnum.ScheduledImmediate.toString());\r
+            else\r
+                cms.setStatus(CMSStatusEnum.Scheduled.toString());\r
+            cmScheduleDAO.save(cms);\r
+        }\r
+        schedule.setStatus(CMSStatusEnum.Scheduled.toString());\r
+        scheduleDAO.save(schedule);\r
+    }\r
+\r
+    private void updateChangeManagementSchedules(Schedule s, CMSStatusEnum approvalrejected) {\r
+        debug.debug("Entered updateChangeManagementSchedules");\r
+        List<ChangeManagementGroup> groups = cmGroupDAO.findBySchedulesID(s.getId());\r
+        for (ChangeManagementGroup group : groups) {\r
+            List<ChangeManagementSchedule> schedules = cmScheduleDAO.findByChangeManagementGroupId(group.getId());\r
+            for (ChangeManagementSchedule schedule : schedules) {\r
+                schedule.setStatus(approvalrejected.toString());\r
+                cmScheduleDAO.save(schedule);\r
+            }\r
+        }\r
+        debug.debug("Exited updateChangeManagementSchedules");\r
+    }\r
+\r
+    @Override\r
+    public Response searchScheduleRequestDetails(String apiVersion, String scheduleId, String scheduleName,\r
+            String userId, String status, String createDateTime, String optimizerStatus, String requestApprovalUserId,\r
+            String requestApprovalStatus, String requestApprovalType, String workflowName, String vnfName, String vnfId,\r
+            String vnfStatus,\r
+            // String vnfScheduleId,\r
+            String startTime, String finishTime, String lastInstanceTime, String tmChangeId,\r
+            // String approvalUserId,\r
+            // String approvalStatus,\r
+            // String approvalType,\r
+            Integer maxSchedules, String lastScheduleId, Integer concurrencyLimit, UriInfo uri,\r
+            HttpServletRequest request) {\r
+\r
+        Mdc.begin(request, UUID.randomUUID().toString());\r
+        Response response = null;\r
+        log.info(LogMessages.SEARCH_SCHEDULE_REQUEST_DETAILS, "Received", request.getRemoteAddr(),\r
+                uri.getRequestUri().getQuery());\r
+        List<CmDetailsMessage> schedules = new ArrayList<CmDetailsMessage>();\r
+\r
+        try {\r
+            log.info("Timezone=" + TimeZone.getDefault());\r
+            MultivaluedMap<String, String> qp = uri.getQueryParameters();\r
+            StringBuilder where = new StringBuilder();\r
+            int maxRows = 0;\r
+            if (maxSchedules != null && maxSchedules > 0)\r
+                maxRows = maxSchedules;\r
+            buildWhere(qp, where);\r
+            List<ChangeManagementDetail> list = cmDetailsDAO.searchScheduleDetails(where.toString(), maxRows);\r
+            if (list == null || !list.iterator().hasNext()) {\r
+                throw new CMSException(Status.NOT_FOUND, LogMessages.SCHEDULE_NOT_FOUND,\r
+                        DomainsEnum.ChangeManagement.toString(), scheduleId);\r
+            }\r
+            Iterator<ChangeManagementDetail> iter = list.iterator();\r
+            Map<Integer, Schedule> scheduleMap = new HashMap<Integer, Schedule>();\r
+            while (iter.hasNext()) {\r
+                ChangeManagementDetail cms = iter.next();\r
+                CmDetailsMessage msg = buildResponse(cms, scheduleMap);\r
+                schedules.add(msg);\r
+            }\r
+            response = Response.ok(schedules.toArray(new CmDetailsMessage[schedules.size()])).build();\r
+        } catch (CMSException e) {\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            log.info(e.getMessage());\r
+            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();\r
+        } catch (Exception e) {\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            response = Response.serverError().build();\r
+        }\r
+        Mdc.end(response);\r
+        log.info(LogMessages.SEARCH_SCHEDULE_REQUEST_DETAILS, "Returned", request.getRemoteAddr(),\r
+                response.getStatusInfo().toString());\r
+        audit.info(LogMessages.SEARCH_SCHEDULE_REQUEST_DETAILS, "Returned", request.getRemoteAddr(),\r
+                response.getStatusInfo().toString());\r
+        metrics.info(LogMessages.SEARCH_SCHEDULE_REQUEST_DETAILS, "Returned", request.getRemoteAddr(),\r
+                response.getStatusInfo().toString());\r
+        return response;\r
+\r
+    }\r
+\r
+    private void buildWhere(MultivaluedMap<String, String> qp, StringBuilder where) throws CMSException {\r
+        String delim = " where ";\r
+        for (String urlName : qp.keySet()) {\r
+            List<String> values = qp.get(urlName);\r
+            String clause = CmQueryParameters.buildClause(urlName, values);\r
+            if (clause != null && !clause.equals("")) {\r
+                where.append(delim).append("\n").append(clause).append("\n");\r
+                delim = "AND";\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    private CmDetailsMessage buildResponse(ChangeManagementDetail cms, Map<Integer, Schedule> scheduleMap) {\r
+        CmDetailsMessage msg = new CmDetailsMessage();\r
+        msg.setVnfId(cms.getVnfId());\r
+        msg.setVnfName(cms.getVnfName());\r
+        msg.setStatus(cms.getStatus());\r
+        msg.setTmChangeId(cms.getTmChangeId());\r
+        msg.setFinishTimeMillis(cms.getFinishTimeMillis());\r
+        msg.setStartTimeMillis(cms.getStartTimeMillis());\r
+        msg.setLastInstanceStartTimeMillis(cms.getLastInstanceStartTimeMillis());\r
+        msg.setGroupId(cms.getGroupId());\r
+        msg.setPolicyId(cms.getPolicyId());\r
+        msg.setTmApprovalStatus(cms.getTmApprovalStatus());\r
+        msg.setTmStatus(cms.getTmStatus());\r
+        msg.setStatusMessage(cms.getStatusMessage());\r
+        msg.setDispatchTimeMillis(cms.getDispatchTimeMillis());\r
+        msg.setExecutionCompletedTimeMillis(cms.getExecutionCompletedTimeMillis());\r
+        msg.setMsoMessage(cms.getMsoMessage());\r
+        msg.setMsoRequestId(cms.getMsoRequestId());\r
+        msg.setMsoStatus(cms.getMsoStatus());\r
+        msg.setMsoTimeMillis(cms.getMsoTimeMillis());\r
+        if (!scheduleMap.containsKey(cms.getSchedulesId())) {\r
+            Schedule schedule = scheduleDAO.findById(cms.getSchedulesId()).orElse(null);\r
+            if (schedule != null) {\r
+                // DO not innclude in the results\r
+                schedule.setScheduleInfo(null);\r
+                // schedule.setSchedule(null);\r
+                scheduleMap.put(cms.getSchedulesId(), schedule);\r
+            }\r
+        }\r
+        if (scheduleMap.containsKey(cms.getSchedulesId())) {\r
+            msg.setScheduleRequest(scheduleMap.get(cms.getSchedulesId()));\r
+        }\r
+        return msg;\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOptimizerCallback.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CMSOptimizerCallback.java
new file mode 100644 (file)
index 0000000..99b4970
--- /dev/null
@@ -0,0 +1,68 @@
+/*\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.service.rs;\r
+\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.ws.rs.DefaultValue;\r
+import javax.ws.rs.POST;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.core.Context;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.UriInfo;\r
+import org.onap.optf.cmso.optimizer.bean.CMOptimizerResponse;\r
+import io.swagger.annotations.Api;\r
+import io.swagger.annotations.ApiOperation;\r
+import io.swagger.annotations.ApiParam;\r
+import io.swagger.annotations.ApiResponse;\r
+import io.swagger.annotations.ApiResponses;\r
+\r
+@Api\r
+@Path("/{apiVersion}")\r
+@Produces({MediaType.APPLICATION_JSON})\r
+public interface CMSOptimizerCallback {\r
+\r
+    // ******************************************************************\r
+    @POST\r
+    @Path("/optimizerCallback")\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "", notes = "Processes optimizer results callback to a Pending Optimization schedule.")\r
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)})\r
+    public Response sniroCallback(\r
+            @ApiParam(value = "v1") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @ApiParam(value = "Return schedules > lastScheduleId") CMOptimizerResponse reponse, @Context UriInfo uri,\r
+            @Context HttpServletRequest request);\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CmQueryParameters.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/CmQueryParameters.java
new file mode 100644 (file)
index 0000000..1a9c29d
--- /dev/null
@@ -0,0 +1,230 @@
+/*\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.service.rs;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.List;\r
+import javax.ws.rs.core.Response.Status;\r
+import org.joda.time.DateTime;\r
+import org.joda.time.format.ISODateTimeFormat;\r
+import org.onap.optf.cmso.common.LogMessages;\r
+import org.onap.optf.cmso.common.exceptions.CMSException;\r
+import org.onap.optf.cmso.model.DomainData;\r
+\r
+public class CmQueryParameters {\r
+\r
+    public enum QueryColumns {\r
+        RequestScheduleId("request.scheduleId", String.class, "ss.schedule_id"), RequestScheduleName(\r
+                "request.scheduleName", String.class,\r
+                "ss.schedule_name"), RequestUserId("request.userId", String.class, "ss.user_id"), RequestStatus(\r
+                        "request.status", String.class, "ss.status"), RequestCreateDateTime("request.createDateTime",\r
+                                Date.class, "ss.create_date_time"), RequestOptimizerStatus("request.optimizerStatus",\r
+                                        String.class, "ss.optimizer_status"), RequestApprovalUserId(\r
+                                                "request.approvalUserId", String.class,\r
+                                                "sa.user_id"), RequestApprovalStatus("request.approvalStatus",\r
+                                                        String.class, "sa.status"), RequestApprovalType(\r
+                                                                "request.approvalType", String.class,\r
+                                                                "at.approval_type"), WorkflowName("WorkflowName",\r
+                                                                        DomainData.class,\r
+                                                                        "dd.value"), vnfName("vnfName", String.class,\r
+                                                                                "s.vnf_name"), vnfId("vnfId",\r
+                                                                                        String.class,\r
+                                                                                        "s.vnf_id"), vnfStatus(\r
+                                                                                                "vnfStatus",\r
+                                                                                                String.class,\r
+                                                                                                "s.vnf_status"),\r
+        // vnfScheduleId("vnfScheduleId", String.class, "s.id"),\r
+        startTime("startTime", Date.class, "s.start_time"), finishTime("finishTime", Date.class,\r
+                "s.finish_ime"), lastInstanceTime("lastInstanceTime", Date.class, "g.last_instance_time"), tmChangeId(\r
+                        "tmChangeId", String.class, "s.tm_change_id"), concurrenyLimit("request.concurrencyLimit",\r
+                                Integer.class, "g.concurrency_limit"),\r
+        // approvalUserId("approvalUserId", String.class, "approvalUserId"),\r
+        // approvalStatus("approvalStatus", String.class, "approvalStatus"),\r
+        // approvalType("approvalType", String.class, "approvalType"),\r
+        ;\r
+\r
+        private final String urlName;\r
+        private final Class<?> type;\r
+        private final String col;\r
+\r
+        private QueryColumns(String urlName, Class<?> type, String col) {\r
+            this.urlName = urlName;\r
+            this.type = type;\r
+            this.col = col;\r
+        }\r
+\r
+    }\r
+\r
+    public static QueryColumns getQueryColumn(String urlName) {\r
+        for (QueryColumns qc : QueryColumns.values()) {\r
+            if (qc.urlName.equals(urlName))\r
+                return qc;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public static String buildClause(String urlName, List<String> values) throws CMSException {\r
+        QueryColumns qc = getQueryColumn(urlName);\r
+        if (qc == null) {\r
+            throw new CMSException(Status.BAD_REQUEST, LogMessages.UNDEFINED_FILTER_ATTRIBUTE, urlName);\r
+        }\r
+        if (qc.type == Date.class) {\r
+            return formatDate(urlName, values, qc);\r
+        }\r
+        if (qc.type == DomainData.class) {\r
+            return formatDomainData(urlName, values, qc);\r
+        }\r
+        return formatString(urlName, values, qc);\r
+    }\r
+\r
+    private static String formatString(String urlName, List<String> values, QueryColumns qc) {\r
+        StringBuilder clause = new StringBuilder();\r
+        List<String> likes = new ArrayList<String>();\r
+        List<String> in = new ArrayList<String>();\r
+        for (String value : values) {\r
+            if (value.contains("%"))\r
+                likes.add(value);\r
+            else\r
+                in.add(value);\r
+        }\r
+        String delim = "(";\r
+        if (in.size() > 0) {\r
+            clause.append(delim).append(qc.col).append(" in ('");\r
+            String inDelim = "";\r
+            for (String value : in) {\r
+                clause.append(inDelim).append(value).append("'");\r
+                inDelim = ", '";\r
+            }\r
+            clause.append(") ");\r
+            delim = " OR ";\r
+        }\r
+        if (likes.size() > 0) {\r
+            for (String value : likes) {\r
+                clause.append(delim).append(qc.col).append(" like '").append(value).append("'");\r
+                delim = " OR ";\r
+            }\r
+        }\r
+        if (!delim.equals("("))\r
+            clause.append(")");\r
+        return clause.toString();\r
+    }\r
+\r
+    private static String formatDomainData(String urlName, List<String> values, QueryColumns qc) {\r
+        StringBuilder clause = new StringBuilder();\r
+        String delim = "(";\r
+        if (values.size() > 0) {\r
+            for (String value : values) {\r
+                clause.append(delim).append(" (dd.name = '").append(qc.urlName).append("' AND dd.value = '")\r
+                        .append(value).append("')");\r
+                delim = " OR ";\r
+            }\r
+        }\r
+        if (!delim.equals("("))\r
+            clause.append(")");\r
+        return clause.toString();\r
+    }\r
+\r
+    private static String formatDate(String urlName, List<String> values, QueryColumns qc) throws CMSException {\r
+        List<String> clauses = new ArrayList<String>();\r
+        for (String value : values) {\r
+            String dates[] = value.split(",");\r
+            switch (dates.length) {\r
+                case 2:\r
+                    formatDatePair(qc, dates[0].trim(), dates[1].trim(), clauses);\r
+                    break;\r
+                case 1:\r
+                    formatDatePair(qc, dates[0].trim(), "", clauses);\r
+                    break;\r
+                default:\r
+                    throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_DATE_FILTER, urlName, value);\r
+            }\r
+        }\r
+        StringBuilder clause = new StringBuilder();\r
+        String delim = "(";\r
+        for (String c : clauses) {\r
+            clause.append(delim).append(c);\r
+            delim = " OR ";\r
+        }\r
+        if (!delim.equals(")")) {\r
+            clause.append(")");\r
+        }\r
+        return clause.toString();\r
+    }\r
+\r
+    private static void formatDatePair(QueryColumns qc, String lowDate, String highDate, List<String> clauses)\r
+            throws CMSException {\r
+        StringBuilder clause = new StringBuilder();\r
+        DateTime date1 = null;\r
+        DateTime date2 = null;\r
+        if (!lowDate.equals(""))\r
+            date1 = convertDate(lowDate, qc.urlName);\r
+        if (!highDate.equals(""))\r
+            date2 = convertDate(highDate, qc.urlName);\r
+        String delim = "(";\r
+        if (date1 != null) {\r
+            clause.append(delim).append(qc.col).append(" >= ").append(date1.getMillis());\r
+            delim = " AND ";\r
+        }\r
+        if (date2 != null) {\r
+            clause.append(delim).append(qc.col).append(" <= ").append(date2.getMillis());\r
+            delim = " AND ";\r
+        }\r
+        if (!delim.equals(")")) {\r
+            clause.append(")\n");\r
+            clauses.add(clause.toString());\r
+        }\r
+    }\r
+\r
+    private static DateTime convertDate(String utcDate, String urlName) throws CMSException {\r
+        DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime(utcDate);\r
+        if (dateTime != null)\r
+            return dateTime;\r
+        throw new CMSException(Status.BAD_REQUEST, LogMessages.INVALID_DATE_FILTER, urlName, utcDate);\r
+    }\r
+\r
+    // public static void main(String argv[])\r
+    // {\r
+    // List<String> values = new ArrayList<String>();\r
+    // values.add("2017-07-08T11:12:13Z,2017-07-08T11:12:13Z");\r
+    // values.add("2017-07-09T11:12:13Z,2017-07-09T11:12:13Z");\r
+    // values.add(",2017-07-09T11:12:13Z");\r
+    // values.add(" 2017-07-09T11:12:13Z");\r
+    // try {\r
+    // System.out.println(buildClause("request.createDateTime", values));\r
+    // } catch (SchedulerException e) {\r
+    // // TODO Auto-generated catch block\r
+    // e.printStackTrace();\r
+    // }\r
+    //\r
+    // }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/HealthCheck.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/HealthCheck.java
new file mode 100644 (file)
index 0000000..edc2c96
--- /dev/null
@@ -0,0 +1,69 @@
+/*\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.service.rs;\r
+\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.ws.rs.DefaultValue;\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.QueryParam;\r
+import javax.ws.rs.core.Context;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.UriInfo;\r
+import org.onap.optf.cmso.service.rs.models.HealthCheckMessage;\r
+import io.swagger.annotations.Api;\r
+import io.swagger.annotations.ApiOperation;\r
+import io.swagger.annotations.ApiParam;\r
+import io.swagger.annotations.ApiResponse;\r
+import io.swagger.annotations.ApiResponses;\r
+\r
+@Api\r
+@Path("/{apiVersion}")\r
+@Produces({MediaType.APPLICATION_JSON})\r
+public interface HealthCheck {\r
+\r
+    // ******************************************************************\r
+    @GET\r
+    @Path("/health")\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "", notes = "Returns health status of server.", response = HealthCheckMessage.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"),\r
+            @ApiResponse(code = 400, message = "Not healthy", response = HealthCheckMessage.class)})\r
+    public Response healthCheck(@ApiParam(value = "v1") @PathParam("apiVersion") @DefaultValue("v1") String apiVersion,\r
+            @DefaultValue(value = "true") @ApiParam(value = "Check Interfaces",\r
+                    allowMultiple = true) @QueryParam("checkInterfaces") Boolean checkInterfaces,\r
+            @Context UriInfo uri, @Context HttpServletRequest request);\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/HealthCheckImpl.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/HealthCheckImpl.java
new file mode 100644 (file)
index 0000000..f994dc8
--- /dev/null
@@ -0,0 +1,121 @@
+/*\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.service.rs;\r
+\r
+import java.util.List;\r
+import java.util.UUID;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.UriInfo;\r
+import org.onap.optf.cmso.common.Mdc;\r
+import org.onap.optf.cmso.model.ApprovalType;\r
+import org.onap.optf.cmso.model.dao.ApprovalTypeDAO;\r
+import org.onap.optf.cmso.optimizer.CMSOptimizerClient;\r
+import org.onap.optf.cmso.service.rs.models.HealthCheckComponent;\r
+import org.onap.optf.cmso.service.rs.models.HealthCheckMessage;\r
+import org.onap.optf.cmso.sostatus.MsoStatusClient;\r
+import org.onap.optf.cmso.ticketmgt.TmClient;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.stereotype.Controller;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+\r
+@Controller\r
+public class HealthCheckImpl implements HealthCheck {\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(HealthCheckImpl.class);\r
+    private static EELFLogger audit = EELFManager.getInstance().getAuditLogger();\r
+\r
+    @Autowired\r
+    TmClient tmClient;\r
+\r
+    @Autowired\r
+    CMSOptimizerClient sniroClient;\r
+\r
+    @Autowired\r
+    ApprovalTypeDAO approvalTypeDAO;\r
+\r
+    @Autowired\r
+    Environment env;\r
+\r
+    @Autowired\r
+    MsoStatusClient msoStatusClient;\r
+\r
+    @Override\r
+    public Response healthCheck(String apiVersion, Boolean checkInterfaces, UriInfo uri, HttpServletRequest request) {\r
+        Mdc.begin(request, UUID.randomUUID().toString());\r
+        log.info("Entered healthcheck");\r
+        Response response = null;\r
+        HealthCheckMessage hc = new HealthCheckMessage();\r
+        hc.setHealthy(true);\r
+\r
+        if (checkInterfaces) {\r
+            addToHealthCheckMessage(hc, tmClient.healthCheck());\r
+            addToHealthCheckMessage(hc, sniroClient.healthCheck());\r
+            addToHealthCheckMessage(hc, msoStatusClient.healthCheck());\r
+        }\r
+        addToHealthCheckMessage(hc, this.healthCheck());\r
+\r
+        if (hc.getHealthy())\r
+            response = Response.ok().entity(hc).build();\r
+        else\r
+            response = Response.status(Response.Status.BAD_REQUEST).entity(hc).build();\r
+        Mdc.end(response);\r
+        audit.info("Healthcheck healthy={0}", hc.getHealthy().toString());\r
+        return response;\r
+    }\r
+\r
+    private void addToHealthCheckMessage(HealthCheckMessage hc, HealthCheckComponent hcc) {\r
+        if (!hcc.getHealthy())\r
+            hc.setHealthy(false);\r
+\r
+        hc.setHostname(System.getenv("HOSTNAME"));\r
+        hc.addComponent(hcc);\r
+    }\r
+\r
+    public HealthCheckComponent healthCheck() {\r
+        HealthCheckComponent hcc = new HealthCheckComponent();\r
+        hcc.setName("Scheduler Database");\r
+        String url = env.getProperty("spring.datasource.url");\r
+        hcc.setUrl(url);\r
+        try {\r
+            List<ApprovalType> approvalTypes = approvalTypeDAO.findByDomain("HealthCheck");\r
+            hcc.setHealthy(true);\r
+            hcc.setStatus("OK");\r
+        } catch (Exception e) {\r
+            hcc.setStatus(e.getMessage());\r
+\r
+        }\r
+        return hcc;\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ApprovalMessage.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ApprovalMessage.java
new file mode 100644 (file)
index 0000000..0d43799
--- /dev/null
@@ -0,0 +1,106 @@
+/*\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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import java.sql.Timestamp;\r
+import org.onap.optf.cmso.common.ApprovalStatusEnum;\r
+import org.onap.optf.cmso.common.ApprovalTypesEnum;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.core.JsonProcessingException;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.annotations.ApiModel;\r
+import io.swagger.annotations.ApiModelProperty;\r
+\r
+/**\r
+ * The persistent class for the approval_types database table.\r
+ * \r
+ */\r
+@ApiModel(value = "Schedule Approval Request", description = "Request to accept or reject an optimized time slot.")\r
+public class ApprovalMessage implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(ApprovalMessage.class);\r
+\r
+    @ApiModelProperty(value = "ATTUID of the user accepting/rejecting the time slot.")\r
+    private String approvalUserId;\r
+\r
+    @ApiModelProperty(value = "Approval status.")\r
+    private ApprovalStatusEnum approvalStatus;\r
+\r
+    @ApiModelProperty(value = "Type of approval.", allowableValues = "Tier 2")\r
+    private ApprovalTypesEnum approvalType;\r
+\r
+    private Timestamp approvalDateTime;\r
+\r
+    public String getApprovalUserId() {\r
+        return approvalUserId;\r
+    }\r
+\r
+    public void setApprovalUserId(String approvalUserId) {\r
+        this.approvalUserId = approvalUserId;\r
+    }\r
+\r
+    public ApprovalStatusEnum getApprovalStatus() {\r
+        return approvalStatus;\r
+    }\r
+\r
+    public void setApprovalStatus(ApprovalStatusEnum approvalStatus) {\r
+        this.approvalStatus = approvalStatus;\r
+    }\r
+\r
+    public ApprovalTypesEnum getApprovalType() {\r
+        return approvalType;\r
+    }\r
+\r
+    public void setApprovalType(ApprovalTypesEnum approvalType) {\r
+        this.approvalType = approvalType;\r
+    }\r
+\r
+    public Timestamp getApprovalDateTime() {\r
+        return approvalDateTime;\r
+    }\r
+\r
+    public void setApprovalDateTime(Timestamp approvalDateTime) {\r
+        this.approvalDateTime = approvalDateTime;\r
+    }\r
+\r
+    public String toString() {\r
+        ObjectMapper mapper = new ObjectMapper();\r
+        try {\r
+            return mapper.writeValueAsString(this);\r
+        } catch (JsonProcessingException e) {\r
+            log.debug("Error in toString()", e);\r
+        }\r
+        return "";\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CMSInfo.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CMSInfo.java
new file mode 100644 (file)
index 0000000..1f7e317
--- /dev/null
@@ -0,0 +1,119 @@
+/*\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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import java.util.List;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.core.JsonProcessingException;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.annotations.ApiModel;\r
+import io.swagger.annotations.ApiModelProperty;\r
+\r
+/**\r
+ * The persistent class for the approval_types database table.\r
+ * \r
+ */\r
+@ApiModel(value = "Change Management Scheduling Info", description = "Details of schedule being requested")\r
+public class CMSInfo implements Serializable {\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(CMSInfo.class);\r
+\r
+    private static final long serialVersionUID = 1L;\r
+\r
+    @ApiModelProperty(value = "Expected duration (in seconds) of a successful execution of a single VNF change.")\r
+    private Integer normalDurationInSeconds;\r
+\r
+    @ApiModelProperty(\r
+            value = "Additional duration (in seconds) to be added to support backout of an unsuccessful VNF change.")\r
+    private Integer additionalDurationInSeconds;\r
+\r
+    @ApiModelProperty(value = "Maximum number of VNF changes to schedule concurrently")\r
+    private Integer concurrencyLimit;\r
+\r
+    @ApiModelProperty(\r
+            value = "Name of schedule optimization policy used by the change management cmso optimizer to determine available time slot")\r
+    private String policyId;\r
+\r
+    @ApiModelProperty(value = "Lists of the VNFs to be changed and the desired change windows")\r
+    private List<VnfDetailsMessage> vnfDetails;\r
+\r
+    public String toString() {\r
+        ObjectMapper mapper = new ObjectMapper();\r
+        try {\r
+            return mapper.writeValueAsString(this);\r
+        } catch (JsonProcessingException e) {\r
+            log.debug("Error in toString()", e);\r
+        }\r
+        return "";\r
+    }\r
+\r
+    public Integer getNormalDurationInSeconds() {\r
+        return normalDurationInSeconds;\r
+    }\r
+\r
+    public void setNormalDurationInSeconds(Integer normalDurationInSeconds) {\r
+        this.normalDurationInSeconds = normalDurationInSeconds;\r
+    }\r
+\r
+    public Integer getAdditionalDurationInSeconds() {\r
+        return additionalDurationInSeconds;\r
+    }\r
+\r
+    public void setAdditionalDurationInSeconds(Integer additionalDurationInSeconds) {\r
+        this.additionalDurationInSeconds = additionalDurationInSeconds;\r
+    }\r
+\r
+    public Integer getConcurrencyLimit() {\r
+        return concurrencyLimit;\r
+    }\r
+\r
+    public void setConcurrencyLimit(Integer concurrencyLimit) {\r
+        this.concurrencyLimit = concurrencyLimit;\r
+    }\r
+\r
+    public String getPolicyId() {\r
+        return policyId;\r
+    }\r
+\r
+    public void setPolicyId(String policyId) {\r
+        this.policyId = policyId;\r
+    }\r
+\r
+    public List<VnfDetailsMessage> getVnfDetails() {\r
+        return vnfDetails;\r
+    }\r
+\r
+    public void setVnfDetails(List<VnfDetailsMessage> vnfDetails) {\r
+        this.vnfDetails = vnfDetails;\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CMSMessage.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CMSMessage.java
new file mode 100644 (file)
index 0000000..afa4c44
--- /dev/null
@@ -0,0 +1,73 @@
+/*\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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import org.onap.optf.cmso.common.LogMessages;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.annotations.ApiModel;\r
+\r
+/**\r
+ * The persistent class for the approval_types database table.\r
+ * \r
+ */\r
+@ApiModel\r
+public class CMSMessage extends ScheduleMessage implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+\r
+    private static EELFLogger errors = EELFManager.getInstance().getErrorLogger();\r
+    private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();\r
+\r
+    private CMSInfo schedulingInfo;\r
+\r
+    @Override\r
+    public CMSInfo getSchedulingInfo() {\r
+        // TODO Auto-generated method stub\r
+        return schedulingInfo;\r
+    }\r
+\r
+    @Override\r
+    public void setSchedulingInfo(Object info) {\r
+        ObjectMapper mapper = new ObjectMapper();\r
+        try {\r
+            String jsonString = mapper.writeValueAsString(info);\r
+            schedulingInfo = mapper.readValue(jsonString, CMSInfo.class);\r
+        } catch (Exception e) {\r
+            debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ChangeWindowMessage.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ChangeWindowMessage.java
new file mode 100644 (file)
index 0000000..58aaa2e
--- /dev/null
@@ -0,0 +1,80 @@
+/*\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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.core.JsonProcessingException;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.annotations.ApiModel;\r
+import io.swagger.annotations.ApiModelProperty;\r
+\r
+@ApiModel(value = "Change Window",\r
+        description = "Time window within which the scheduler optimizer can schedule the changes for the  group of NVFs")\r
+public class ChangeWindowMessage implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(ChangeWindowMessage.class);\r
+\r
+    @ApiModelProperty(value = "Earliest time that a set of changes may begin.")\r
+    private String startTime;\r
+\r
+    @ApiModelProperty(value = "Latest time by which all changes must be completed")\r
+    private String endTime;\r
+\r
+    public String getStartTime() {\r
+        return startTime;\r
+    }\r
+\r
+    public void setStartTime(String startTime) {\r
+        this.startTime = startTime;\r
+    }\r
+\r
+    public String getEndTime() {\r
+        return endTime;\r
+    }\r
+\r
+    public void setEndTime(String endTime) {\r
+        this.endTime = endTime;\r
+    }\r
+\r
+    public String toString() {\r
+        ObjectMapper mapper = new ObjectMapper();\r
+        try {\r
+            return mapper.writeValueAsString(this);\r
+        } catch (JsonProcessingException e) {\r
+            log.debug("Error in toString()", e);\r
+        }\r
+        return "";\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CmDetailsMessage.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CmDetailsMessage.java
new file mode 100644 (file)
index 0000000..b021af9
--- /dev/null
@@ -0,0 +1,67 @@
+/*\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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import java.util.List;\r
+import org.onap.optf.cmso.model.ChangeManagementDetail;\r
+import org.onap.optf.cmso.model.Schedule;\r
+import io.swagger.annotations.ApiModel;\r
+\r
+/**\r
+ * The persistent class for the change_management_groups database table.\r
+ * \r
+ */\r
+@ApiModel\r
+public class CmDetailsMessage extends ChangeManagementDetail implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+\r
+    private Schedule scheduleRequest;\r
+    private List<ApprovalMessage> approvals;\r
+\r
+    public Schedule getScheduleRequest() {\r
+        return scheduleRequest;\r
+    }\r
+\r
+    public void setScheduleRequest(Schedule scheduleRequest) {\r
+        this.scheduleRequest = scheduleRequest;\r
+    }\r
+\r
+    public List<ApprovalMessage> getApprovals() {\r
+        return approvals;\r
+    }\r
+\r
+    public void setApprovals(List<ApprovalMessage> approvals) {\r
+        this.approvals = approvals;\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CmDomainDataEnum.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/CmDomainDataEnum.java
new file mode 100644 (file)
index 0000000..675a8d9
--- /dev/null
@@ -0,0 +1,46 @@
+/*\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.service.rs.models;\r
+\r
+public enum CmDomainDataEnum {\r
+    WorkflowName(true), CallbackUrl(true), ServiceType(false), VnfType(false), SubscriberName(false), CallbackData(\r
+            true),;\r
+    private final Boolean required;\r
+\r
+    private CmDomainDataEnum(boolean required) {\r
+        this.required = required;\r
+    }\r
+\r
+    public boolean isRequired() {\r
+        return required;\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/HealthCheckComponent.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/HealthCheckComponent.java
new file mode 100644 (file)
index 0000000..47d8d57
--- /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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.core.JsonProcessingException;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.annotations.ApiModel;\r
+\r
+@ApiModel\r
+public class HealthCheckComponent implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(HealthCheckComponent.class);\r
+\r
+    private String name;\r
+    private String url;\r
+    private String status;\r
+    private Boolean healthy = false;\r
+\r
+    public Boolean getHealthy() {\r
+        return healthy;\r
+    }\r
+\r
+    public void setHealthy(Boolean healthy) {\r
+        this.healthy = healthy;\r
+    }\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public String getUrl() {\r
+        return url;\r
+    }\r
+\r
+    public void setUrl(String url) {\r
+        this.url = url;\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 toString() {\r
+        ObjectMapper mapper = new ObjectMapper();\r
+        try {\r
+            return mapper.writeValueAsString(this);\r
+        } catch (JsonProcessingException e) {\r
+            log.debug("Error in toString()", e);\r
+        }\r
+        return "";\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/HealthCheckMessage.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/HealthCheckMessage.java
new file mode 100644 (file)
index 0000000..02cc65f
--- /dev/null
@@ -0,0 +1,108 @@
+/*\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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.core.JsonProcessingException;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.annotations.ApiModel;\r
+\r
+@ApiModel\r
+public class HealthCheckMessage implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(HealthCheckMessage.class);\r
+\r
+    private Boolean healthy = false;\r
+    private String buildInfo = "";\r
+    private String currentTime = "";\r
+    private String hostname = "";\r
+\r
+    private List<HealthCheckComponent> components = new ArrayList<HealthCheckComponent>();\r
+\r
+    public Boolean getHealthy() {\r
+        return healthy;\r
+    }\r
+\r
+    public void setHealthy(Boolean healthy) {\r
+        this.healthy = healthy;\r
+    }\r
+\r
+    public String getBuildInfo() {\r
+        return buildInfo;\r
+    }\r
+\r
+    public void setBuildInfo(String buildInfo) {\r
+        this.buildInfo = buildInfo;\r
+    }\r
+\r
+    public String getCurrentTime() {\r
+        return currentTime;\r
+    }\r
+\r
+    public void setCurrentTime(String currentTime) {\r
+        this.currentTime = currentTime;\r
+    }\r
+\r
+    public String getHostname() {\r
+        return hostname;\r
+    }\r
+\r
+    public void setHostname(String hostname) {\r
+        this.hostname = hostname;\r
+    }\r
+\r
+    public List<HealthCheckComponent> getComponents() {\r
+        return components;\r
+    }\r
+\r
+    public void setComponents(List<HealthCheckComponent> components) {\r
+        this.components = components;\r
+    }\r
+\r
+    public void addComponent(HealthCheckComponent components) {\r
+        this.components.add(components);\r
+    }\r
+\r
+    public String toString() {\r
+        ObjectMapper mapper = new ObjectMapper();\r
+        try {\r
+            return mapper.writeValueAsString(this);\r
+        } catch (JsonProcessingException e) {\r
+            log.debug("Error in toString()", e);\r
+        }\r
+        return "";\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ScheduleMessage.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/ScheduleMessage.java
new file mode 100644 (file)
index 0000000..a89e818
--- /dev/null
@@ -0,0 +1,124 @@
+/*\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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import java.util.List;\r
+import java.util.Map;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.core.JsonProcessingException;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.annotations.ApiModel;\r
+import io.swagger.annotations.ApiModelProperty;\r
+\r
+/**\r
+ * The persistent class for the approval_types database table.\r
+ * \r
+ */\r
+@ApiModel(value = "Schedule Request", description = "Request to schedule VNF change management workflow(s).")\r
+public abstract class ScheduleMessage implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(ScheduleMessage.class);\r
+\r
+    public abstract Object getSchedulingInfo();\r
+\r
+    public abstract void setSchedulingInfo(Object info);\r
+\r
+    // public abstract void setSchedulingInfo(Object schedulingInfo);\r
+\r
+    @ApiModelProperty(value = "Schedule domain : ChangeManagement")\r
+    private String domain;\r
+\r
+    @ApiModelProperty(value = "Schedule id that must be unique within the domain. Use of UUID is highly recommended.")\r
+    private String scheduleId;\r
+\r
+    @ApiModelProperty(value = "User provided name of the schedule (deaults to scheduleId")\r
+    private String scheduleName;\r
+\r
+    @ApiModelProperty(value = "ATTUID of the user requesting the schedule.")\r
+    private String userId;\r
+\r
+    @ApiModelProperty(value = "Domain data as name value/pairs. (i.e. CallbackUrl, CallbackData, WorkflowName)")\r
+    private List<Map<String, String>> domainData;\r
+\r
+    public String getDomain() {\r
+        return domain;\r
+    }\r
+\r
+    public void setDomain(String domain) {\r
+        this.domain = domain;\r
+    }\r
+\r
+    public String getScheduleId() {\r
+        return scheduleId;\r
+    }\r
+\r
+    public void setScheduleId(String scheduleId) {\r
+        this.scheduleId = scheduleId;\r
+    }\r
+\r
+    public String getScheduleName() {\r
+        return scheduleName;\r
+    }\r
+\r
+    public void setScheduleName(String scheduleName) {\r
+        this.scheduleName = scheduleName;\r
+    }\r
+\r
+    public String getUserId() {\r
+        return userId;\r
+    }\r
+\r
+    public void setUserId(String userId) {\r
+        this.userId = userId;\r
+    }\r
+\r
+    public List<Map<String, String>> getDomainData() {\r
+        return domainData;\r
+    }\r
+\r
+    public void setDomainData(List<Map<String, String>> domainData) {\r
+        this.domainData = domainData;\r
+    }\r
+\r
+    public String toString() {\r
+        ObjectMapper mapper = new ObjectMapper();\r
+        try {\r
+            return mapper.writeValueAsString(this);\r
+        } catch (JsonProcessingException e) {\r
+            log.debug("Error in toString()", e);\r
+        }\r
+        return "";\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/VnfDetailsMessage.java b/cmso-service/src/main/java/org/onap/optf/cmso/service/rs/models/VnfDetailsMessage.java
new file mode 100644 (file)
index 0000000..b1dde5d
--- /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.service.rs.models;\r
+\r
+import java.io.Serializable;\r
+import java.util.List;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.core.JsonProcessingException;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import io.swagger.annotations.ApiModel;\r
+import io.swagger.annotations.ApiModelProperty;\r
+\r
+@ApiModel(value = "VNF Details", description = "Details and scheduling criteria for the VNFs to be changed.")\r
+public class VnfDetailsMessage implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(VnfDetailsMessage.class);\r
+\r
+    @ApiModelProperty(value = "Name of the list of VNFs to be changed as a group")\r
+    private String groupId;\r
+\r
+    @ApiModelProperty(value = "Lists of the VNF names to be changed")\r
+    private List<String> node;\r
+\r
+    @ApiModelProperty(\r
+            value = "Lists of desired change windows that the optimizer can select from. (Only 1 change window supported at this time)")\r
+    private List<ChangeWindowMessage> changeWindow;\r
+\r
+    public String getGroupId() {\r
+        return groupId;\r
+    }\r
+\r
+    public void setGroupId(String groupId) {\r
+        this.groupId = groupId;\r
+    }\r
+\r
+    public List<String> getNode() {\r
+        return node;\r
+    }\r
+\r
+    public void setNode(List<String> node) {\r
+        this.node = node;\r
+    }\r
+\r
+    public List<ChangeWindowMessage> getChangeWindow() {\r
+        return changeWindow;\r
+    }\r
+\r
+    public void setChangeWindow(List<ChangeWindowMessage> changeWindow) {\r
+        this.changeWindow = changeWindow;\r
+    }\r
+\r
+    public String toString() {\r
+        ObjectMapper mapper = new ObjectMapper();\r
+        try {\r
+            return mapper.writeValueAsString(this);\r
+        } catch (JsonProcessingException e) {\r
+            log.debug("Error in toString()", e);\r
+        }\r
+        return "";\r
+    }\r
+\r
+}\r