From 4639a66f22d841bd4b44bdd554e62c311c4c1a37 Mon Sep 17 00:00:00 2001 From: "RamaPrasad Amaranarayana (ra5425)" Date: Wed, 19 Sep 2018 18:42:58 -0400 Subject: Change Management Schedule Optimization Adding CMSO Service Code for Change Management Schedule Optimization Change-Id: I11d98eb24544bc5fda0be64d196433cf67917a7a Issue-ID: OPTFRA-353 Signed-off-by: RamaPrasad Amaranarayana (ra5425) --- .../loopback/SchedulerTestLoopbackService.java | 87 +++++++++ .../loopback/SchedulerTestLoopbackServiceImpl.java | 215 +++++++++++++++++++++ .../test/loopback/TicketMgtLoopbackService.java | 93 +++++++++ .../loopback/TicketMgtLoopbackServiceImpl.java | 93 +++++++++ 4 files changed, 488 insertions(+) create mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/SchedulerTestLoopbackService.java create mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/SchedulerTestLoopbackServiceImpl.java create mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/TicketMgtLoopbackService.java create mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/TicketMgtLoopbackServiceImpl.java (limited to 'cmso-service/src/main') diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/SchedulerTestLoopbackService.java b/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/SchedulerTestLoopbackService.java new file mode 100644 index 0000000..f75365a --- /dev/null +++ b/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/SchedulerTestLoopbackService.java @@ -0,0 +1,87 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.test.loopback; + +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import org.onap.optf.cmso.optimizer.bean.CMOptimizerRequest; +import org.onap.optf.cmso.so.bean.MsoOrchestrationQueryResponse; +import org.onap.optf.cmso.wf.bean.WfChangeManagementResponse; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +@Api +@Path("/v1/loopbacktest") +@Produces({MediaType.APPLICATION_JSON}) +public interface SchedulerTestLoopbackService { + // ****************************************************************** + @POST + @Path("/optimizer") + @Produces({MediaType.APPLICATION_JSON}) + @ApiOperation(value = "", notes = "Test Optimizer connection in loopback mode.") + @ApiResponses(value = {@ApiResponse(code = 202, message = "OK"), + @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)}) + public Response putToOptimizer(@ApiParam(value = "SNIRO request message") CMOptimizerRequest request, + @Context UriInfo uri); + + // ****************************************************************** + @POST + @Path("/onap/so/infra/orchestrationRequests/v7/schedule/{vnfName}") + @Produces({MediaType.APPLICATION_JSON}) + @ApiOperation(value = "", notes = "Test SO sheduling in loopback mode.", + response = WfChangeManagementResponse.class) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"), + @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)}) + public Response soScheduleLoopback(@ApiParam(value = "vnfName") @PathParam("vnfName") String vnfName, + @ApiParam(value = "SO request message") String request, @Context UriInfo uri); + + // ****************************************************************** + @GET + @Path("/onap/so/infra/orchestrationRequests/v7/{requestId}") + @Produces({MediaType.APPLICATION_JSON}) + @ApiOperation(value = "", notes = "Test SO Status query loopback.", response = MsoOrchestrationQueryResponse.class) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"), + @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)}) + public Response soQueryLoopback(@ApiParam(value = "MSO request ID") @PathParam("requestId") String requestId, + @Context UriInfo uri); + +} diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/SchedulerTestLoopbackServiceImpl.java b/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/SchedulerTestLoopbackServiceImpl.java new file mode 100644 index 0000000..b240b61 --- /dev/null +++ b/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/SchedulerTestLoopbackServiceImpl.java @@ -0,0 +1,215 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.test.loopback; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.ResponseProcessingException; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import org.onap.optf.cmso.common.BasicAuthenticatorFilter; +import org.onap.optf.cmso.common.LogMessages; +import org.onap.optf.cmso.common.PropertiesManagement; +import org.onap.optf.cmso.optimizer.bean.CMOptimizerRequest; +import org.onap.optf.cmso.optimizer.bean.CMOptimizerResponse; +import org.onap.optf.cmso.optimizer.bean.CMRequestInfo; +import org.onap.optf.cmso.optimizer.bean.CMSchedule; +import org.onap.optf.cmso.optimizer.bean.CMSchedulingInfo; +import org.onap.optf.cmso.optimizer.bean.CMVnfDetails; +import org.onap.optf.cmso.service.rs.CMSCallbackImpl; +import org.onap.optf.cmso.wf.bean.WfCmResponse200; +import org.onap.optf.cmso.wf.bean.WfMsoRequestReferences; +import org.onap.optf.cmso.wf.bean.WfMsoResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Controller; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +@Controller +public class SchedulerTestLoopbackServiceImpl implements SchedulerTestLoopbackService { + private static EELFLogger log = EELFManager.getInstance().getLogger(SchedulerTestLoopbackServiceImpl.class); + private static EELFLogger debug = EELFManager.getInstance().getDebugLogger(); + private static EELFLogger errors = EELFManager.getInstance().getErrorLogger(); + + @Autowired + Environment env; + + @Autowired + PropertiesManagement pm; + + @Override + public Response putToOptimizer(CMOptimizerRequest request, UriInfo uri) { + // + try { + CMOptimizerResponse r = new CMOptimizerResponse(); + CMRequestInfo ri = request.getRequestInfo(); + CMSchedulingInfo si = request.getSchedulingInfo(); + r.setTransactionId(ri.getTransactionId()); + r.setRequestState("Done."); + r.setScheduleId(ri.getRequestId()); + String callback = ri.getCallbackUrl(); + + // This is a dumb opt. WIll not make sense for multiple groups + // Use the code in the callback to help + List nodes = new ArrayList(); + // get total number of nodes across all groups. + for (CMVnfDetails sr : si.getVnfDetails()) { + nodes.add(sr.getNode()); + } + + DateTime startTime = CMSCallbackImpl.convertISODate(si.getStartTime(), "startTime"); + + // Ignore the finish time for now in the calc. Just accept what they + // gave + DateTime finishTime = CMSCallbackImpl.convertISODate(si.getEndTime(), "endTime"); + DateTimeFormatter sniroFmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZoneUTC(); + + int add = si.getAdditionalDurationInSecs(); + int normal = si.getNormalDurationInSecs(); + int concurrencyLimit = si.getConcurrencyLimit(); + long totalDuration = (long) add + normal; + long serialized = 0; + if (nodes.size() > concurrencyLimit) { + serialized = (nodes.size() / concurrencyLimit); + serialized = (serialized * totalDuration) * 1000; + } + DateTime latestInstanceStartTime = startTime.plus(serialized); + finishTime = latestInstanceStartTime.plus(totalDuration * 1000); + // Reformat request into a response setting the groups start finish + // time based upon + Map map = new HashMap(); + for (CMVnfDetails sr : si.getVnfDetails()) { + String groupId = sr.getGroupId(); + CMSchedule cms = map.get(groupId); + if (cms == null) { + cms = new CMSchedule(); + cms.setGroupId(groupId); + cms.setFinishTime(groupId); + map.put(groupId, cms); + cms.setStartTime(sniroFmt.print(startTime)); + cms.setFinishTime(sniroFmt.print(finishTime)); + cms.setLatestInstanceStartTime(sniroFmt.print(latestInstanceStartTime)); + } + cms.getNode().add(sr.getNode()); + } + r.setSchedule(map.values().toArray(new CMSchedule[map.values().size()])); + + Thread responseThread = new Thread(new Runnable() { + public void run() { + sendAsyncResponse(r, callback); + } + }); + responseThread.start(); + + return Response.accepted().build(); + } catch (Exception e) { + log.error("Unexpected exception", e); + } + return Response.serverError().build(); + } + + private void sendAsyncResponse(CMOptimizerResponse r, String url) { + try { + Client client = ClientBuilder.newClient(); + String user = env.getProperty("mechid.user", ""); + String pass = pm.getProperty("mechid.pass", ""); + client.register(new BasicAuthenticatorFilter(user, pass)); + WebTarget target = client.target(url); + Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON); + try { + Response response = invocationBuilder.post(Entity.json(r)); + switch (response.getStatus()) { + case 202: + // Scheduled with SNIRO + break; + case 400: // Bad request + case 500: + default: { + } + } + } catch (ResponseProcessingException e) { + errors.error(LogMessages.OPTIMIZER_EXCEPTION, e, e.getMessage()); + debug.debug(LogMessages.OPTIMIZER_EXCEPTION, e, e.getMessage()); + + } catch (ProcessingException e) { + log.error(LogMessages.OPTIMIZER_EXCEPTION.toString(), e); + log.error(LogMessages.OPTIMIZER_EXCEPTION, e.getMessage()); + } + } catch (Exception e) { + errors.error(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); + debug.debug(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); + + } + } + + public Response soScheduleLoopback(String vnfName, String request, UriInfo uri) { + String msoRequestId = env.getProperty("loopback.mso.requestId", "4ccbfb85-1d05-442e"); + String r = UUID.randomUUID().toString(); + WfMsoRequestReferences rr = new WfMsoRequestReferences(); + rr.setInstanceId(r); + rr.setRequestId(msoRequestId); + WfMsoResponse mso = new WfMsoResponse(); + mso.setRequestReferences(rr); + WfCmResponse200 cmResponse = new WfCmResponse200(); + cmResponse.setEntity(mso); + cmResponse.setStatus(202);; + return Response.status(Status.OK).entity(cmResponse).build(); + } + + @Override + public Response soQueryLoopback(String requestId, UriInfo uri) { + // Abbreviated response. Only interested in requestStatus.... + String response = "{\"request\" : {" + "\"requestId\" : \"dummy-request-id\"," + + "\"startTime\" : \"Wed, 26 Aug 2017 06:36:07 GMT\"," + "\"requestScope\" : \"vfModule\"," + + "\"requestType\" : \"createInstance\"," + "\"requestDetails\" : {}," + "\"instanceReferences\" : {}," + + "\"requestStatus\" : { " + "\"requestState\" : \"COMPLETE\"," + + "\"statusMessage\" : \"Vf Module has been created successfully.\"," + "\"percentProgress\" : 100," + + "\"finishTime\" : \"Crap so cmso uses current time\"}}}"; + return Response.ok().entity(response).build(); + } + +} diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/TicketMgtLoopbackService.java b/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/TicketMgtLoopbackService.java new file mode 100644 index 0000000..d2953b6 --- /dev/null +++ b/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/TicketMgtLoopbackService.java @@ -0,0 +1,93 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.test.loopback; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import com.fasterxml.jackson.databind.JsonNode; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +@Api +@Path("/v1/tm") +@Produces({MediaType.APPLICATION_JSON}) +public interface TicketMgtLoopbackService { + + // ****************************************************************** + @POST + @Path("/getChangeRecord") + @Produces({MediaType.APPLICATION_JSON}) + @ApiOperation(value = "", notes = "Dummy out ticket management check status call.", response = JsonNode.class) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"), + @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)}) + public Response tmGetChangeRecord(@ApiParam(value = "TM request message") JsonNode request, @Context UriInfo uri); + + // ****************************************************************** + @POST + @Path("/createChangeRecord") + @Produces({MediaType.APPLICATION_JSON}) + @ApiOperation(value = "", notes = "Dummy out ticket management create call.", response = JsonNode.class) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"), + @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)}) + public Response tmCreateChangeRecord(@ApiParam(value = "TM request message") JsonNode request, + @Context UriInfo uri); + + // ****************************************************************** + @POST + @Path("/closeCancelChangeRecord") + @Produces({MediaType.APPLICATION_JSON}) + @ApiOperation(value = "", notes = "Dummy out ticket management close call.", response = JsonNode.class) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"), + @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)}) + public Response tmCloseCancelChangeRecord(@ApiParam(value = "TM request message") JsonNode request, + @Context UriInfo uri); + + // ****************************************************************** + @POST + @Path("/updateChangeRecord") + @Produces({MediaType.APPLICATION_JSON}) + @ApiOperation(value = "", notes = "Dummy out ticket management update to in progress call.", + response = JsonNode.class) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK"), + @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)}) + public Response tmUpdateChangeRecord(@ApiParam(value = "TM request message") JsonNode request, + @Context UriInfo uri); + +} diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/TicketMgtLoopbackServiceImpl.java b/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/TicketMgtLoopbackServiceImpl.java new file mode 100644 index 0000000..1c87f66 --- /dev/null +++ b/cmso-service/src/main/java/org/onap/optf/cmso/test/loopback/TicketMgtLoopbackServiceImpl.java @@ -0,0 +1,93 @@ +/* + * Copyright © 2017-2018 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.test.loopback; + +import java.util.HashMap; +import java.util.Map; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import org.onap.optf.cmso.common.PropertiesManagement; +import org.onap.optf.cmso.ticketmgt.bean.TmApprovalStatusEnum; +import org.onap.optf.cmso.ticketmgt.bean.TmChangeInfo; +import org.onap.optf.cmso.ticketmgt.bean.TmStatusEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Controller; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +@Controller +public class TicketMgtLoopbackServiceImpl implements TicketMgtLoopbackService { + private static EELFLogger log = EELFManager.getInstance().getLogger(TicketMgtLoopbackServiceImpl.class); + private static EELFLogger debug = EELFManager.getInstance().getDebugLogger(); + private static EELFLogger errors = EELFManager.getInstance().getErrorLogger(); + + @Autowired + Environment env; + + PropertiesManagement pm; + + @Override + public Response tmGetChangeRecord(JsonNode request, UriInfo uri) { + TmChangeInfo changeInfo = new TmChangeInfo(); + changeInfo.setChangeId("CHG000000000001"); + changeInfo.setStatus(TmStatusEnum.Scheduled.toString()); + changeInfo.setApprovalStatus(TmApprovalStatusEnum.Approved.toString()); + return Response.ok().entity(changeInfo).build(); + } + + @Override + public Response tmCreateChangeRecord(JsonNode request, UriInfo uri) { + Map response = new HashMap(); + response.put("changeId", "CHG000000000001"); + return Response.ok().entity(response).build(); + } + + @Override + public Response tmCloseCancelChangeRecord(JsonNode request, UriInfo uri) { + ObjectNode req = (ObjectNode) request; + String changeId = req.get("changeId").asText(); + String resp = changeId + " was update successfully."; + return Response.ok().entity(resp).build(); + } + + @Override + public Response tmUpdateChangeRecord(JsonNode request, UriInfo uri) { + ObjectNode req = (ObjectNode) request; + String changeId = req.get("changeId").asText(); + String resp = changeId + " was updated successfully."; + return Response.ok().entity(resp).build(); + } + +} -- cgit 1.2.3-korg