Update API to support async requests 66/82466/1
authorJerry Flood <jflood@att.com>
Fri, 15 Mar 2019 16:11:34 +0000 (12:11 -0400)
committerJerry Flood <jflood@att.com>
Fri, 15 Mar 2019 17:02:42 +0000 (13:02 -0400)
Change-Id: Icde7d336d11517e60e7ab518c76faef8e917de3e
Issue-ID: OPTFRA-433
Signed-off-by: Jerry Flood <jflood@att.com>
cmso-ticketmgt/src/main/java/org/onap/optf/ticketmgt/common/LogMessages.java
cmso-ticketmgt/src/main/java/org/onap/optf/ticketmgt/service/rs/AvailabilityInterface.java
cmso-ticketmgt/src/main/java/org/onap/optf/ticketmgt/service/rs/AvailabilityInterfaceImpl.java
cmso-ticketmgt/src/main/java/org/onap/optf/ticketmgt/service/rs/TicketManagement.java
cmso-ticketmgt/src/main/java/org/onap/optf/ticketmgt/service/rs/models/ActiveTicketsResponse.java
cmso-ticketmgt/src/main/resources/logmessages.properties

index f16c94c..caf7e8b 100644 (file)
@@ -52,6 +52,8 @@ public enum LogMessages implements ObservationInterface {
        UPDATE_TICKET("Update ticket {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
        GET_ACTIVE_TICKETS("Get active tickets {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
        SEARCH_TICKETS("Search tickets {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
+       DELETE_ACTIVE_TICKETS("Delete active tickets {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
+       POLL_ACTIVE_TICKETS("Polling active tickets {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
        
        TICKET_NOT_FOUND("Ticket not found id={0}", Status.NOT_FOUND, Level.INFO),
        INVALID_ATTRIBUTE("Invalid attribute {0}={1}", Status.BAD_REQUEST, Level.INFO),
@@ -73,7 +75,7 @@ public enum LogMessages implements ObservationInterface {
        EXPECTED_EXCEPTION("Expected exception encountered during processing. {0}", Status.OK, Level.INFO),
        UNABLE_TO_UPDATE_TICKET("Unable to update change ticket in TM: Schedule ID: {0} : changeid: {1} :  Reason: {2}", Status.OK, Level.INFO),
        UNAUTHORIZED("Authorization failed.", Status.FORBIDDEN, Level.INFO),
-       UNAUTHENTICATED("Authentication failed.", Status.UNAUTHORIZED, Level.INFO), 
+       UNAUTHENTICATED("Authentication failed.", Status.UNAUTHORIZED, Level.INFO),  
        
        ;
        private final String defaultId;
index b4b3626..60fccd1 100644 (file)
@@ -31,7 +31,9 @@
 
 package org.onap.optf.ticketmgt.service.rs;
 
+import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
@@ -63,8 +65,10 @@ public interface AvailabilityInterface {
     @Produces({MediaType.APPLICATION_JSON})
     @RequestMapping(value = "/{apiVersion}/activetickets", method = RequestMethod.POST, 
                consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)
-    @ApiOperation(value = "", notes = "API to support conflict avoidance. Retrieves the active ticket data for the "
-               + "passed criteria to detemine availability of passed elements within the passed time window", 
+    @ApiOperation(value = "Request Active Tickets", notes = "API to support conflict avoidance. Retrieves the active ticket data for the "
+               + "passed criteria to detemine availability of passed elements within the passed time window."
+               + "\nIf the request results in asynchronous processging, IN_PROGRESS status will be returned and the "
+               + "optimizer will begin to poll the request until COMPLETED.", 
                response = ActiveTicketsResponse.class)
     @ApiResponses(
             value = {@ApiResponse(code = 200, message = "OK"), 
@@ -75,6 +79,41 @@ public interface AvailabilityInterface {
             @ApiParam(value = "Active ticket criteria (elements and change windows).")  ActiveTicketsRequest activeTicketsRequest
             );
 
+    @GET
+    @Path("/activetickets/{id}")
+    @Produces({MediaType.APPLICATION_JSON})
+    @RequestMapping(value = "/{apiVersion}/activetickets/{id}", method = RequestMethod.GET, 
+               consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)
+    @ApiOperation(value = "Poll Active Tickets Request", notes = "Poll for the status of the request id. Optimizser will "
+               + " poll until status is COMPLETED and issue acknowledge (DELETE) API to acknowledge the "
+               + "receipt of the response.", 
+               response = ActiveTicketsResponse.class)
+    @ApiResponses(
+            value = {@ApiResponse(code = 200, message = "OK"), 
+                       @ApiResponse(code = 404, message = "Not found.", response = CMSRequestError.class),
+                    @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)})
+    public Response pollActiveTickets(
+            @ApiParam(value = "v1") @PathParam("apiVersion") @PathVariable(value="v1") @DefaultValue("v1") String apiVersion,
+            @ApiParam(value = "Active tickets request id.")  @PathParam("id") String id
+            );
+
+    @DELETE
+    @Path("/activetickets/{id}")
+    @Produces({MediaType.APPLICATION_JSON})
+    @RequestMapping(value = "/{apiVersion}/activetickets/{id}", method = RequestMethod.DELETE, 
+               consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)
+    @ApiOperation(value = "Acknowledge Active Tickets Response", notes = "API call used to acknowledge the receipt"
+               + " of a COMPLETED asynchronous request to enable the Ticket Management service to remove it from their cache."
+               + " The service may remove from the cache on the poll request. The optimizer will treat Not found reponse on as normal.", 
+               response = ActiveTicketsResponse.class)
+    @ApiResponses(
+            value = {@ApiResponse(code = 204, message = "OK"), 
+                       @ApiResponse(code = 404, message = "Not found", response = CMSRequestError.class),
+                    @ApiResponse(code = 500, message = "Unexpected Runtime error", response = Exception.class)})
+    public Response deleteActiveTicketsRequest(
+            @ApiParam(value = "v1") @PathParam("apiVersion") @PathVariable(value="v1") @DefaultValue("v1") String apiVersion,
+            @ApiParam(value = "Active tickets request id.")  @PathParam("id") String id
+            );
 
 
 }
index 1120983..9538f46 100644 (file)
@@ -40,6 +40,7 @@ import org.onap.observations.Observation;
 import org.onap.optf.ticketmgt.common.LogMessages;
 import org.onap.optf.ticketmgt.service.rs.models.ActiveTicketsRequest;
 import org.onap.optf.ticketmgt.service.rs.models.ActiveTicketsResponse;
+import org.onap.optf.ticketmgt.service.rs.models.ActiveTicketsResponse.ActiveTicketResponseStatus;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Controller;
@@ -73,6 +74,7 @@ public class AvailabilityInterfaceImpl  implements AvailabilityInterface {
         {
                ActiveTicketsResponse atr = new ActiveTicketsResponse();
                atr.setRequestId(activeTicketsRequest.getRequestId());
+               atr.setStatus(ActiveTicketResponseStatus.COMPLETED);
             response = Response.ok(atr).build();
 //        } catch (CMSException e) {
 //            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@@ -86,4 +88,51 @@ public class AvailabilityInterfaceImpl  implements AvailabilityInterface {
         Observation.report(LogMessages.GET_ACTIVE_TICKETS, "Returned", request.getRemoteAddr(), id, response.getStatusInfo().toString());
                return response;
        }
+
+
+       @Override
+       public Response pollActiveTickets(String apiVersion, String id) {
+               // TODO Auto-generated method stub
+        Observation.report(LogMessages.POLL_ACTIVE_TICKETS, "Received", request.getRemoteAddr(), id, "");
+        Response response = null;
+        try 
+        {
+               ActiveTicketsResponse atr = new ActiveTicketsResponse();
+               atr.setRequestId(id);
+               atr.setStatus(ActiveTicketResponseStatus.COMPLETED);
+            response = Response.ok(atr).build();
+//        } catch (CMSException e) {
+//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+//             Observation.report(LogMessages.EXPECTED_EXCEPTION, e, e.getMessage());
+//            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();
+        } catch (Exception e) {
+               Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            response = Response.serverError().build();
+        }
+        Observation.report(LogMessages.POLL_ACTIVE_TICKETS, "Returned", request.getRemoteAddr(), id, response.getStatusInfo().toString());
+               return response;
+       }
+
+
+       @Override
+       public Response deleteActiveTicketsRequest(String apiVersion, String id) {
+               // TODO Auto-generated method stub
+        Observation.report(LogMessages.DELETE_ACTIVE_TICKETS, "Received", request.getRemoteAddr(), id, "");
+        Response response = null;
+        try 
+        {
+            response = Response.noContent().build();
+//        } catch (CMSException e) {
+//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+//             Observation.report(LogMessages.EXPECTED_EXCEPTION, e, e.getMessage());
+//            response = Response.status(e.getStatus()).entity(e.getRequestError()).build();
+        } catch (Exception e) {
+               Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            response = Response.serverError().build();
+        }
+        Observation.report(LogMessages.DELETE_ACTIVE_TICKETS, "Returned", request.getRemoteAddr(), id, response.getStatusInfo().toString());
+               return response;
+       }
 }
index 1931296..13e7f6d 100644 (file)
@@ -31,7 +31,6 @@
 
 package org.onap.optf.ticketmgt.service.rs;
 
-import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
@@ -41,10 +40,8 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
-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.common.CMSRequestError;
 import org.onap.optf.ticketmgt.service.rs.models.TicketData;
index d26fc6f..d3d5f7d 100644 (file)
@@ -48,12 +48,23 @@ public class ActiveTicketsResponse implements Serializable {
     private static final long serialVersionUID = 1L;
     private static EELFLogger log = EELFManager.getInstance().getLogger(ActiveTicketsResponse.class);
 
+    public enum ActiveTicketResponseStatus
+    {
+       IN_PROGESS,
+       COMPLETED,
+    }
     @ApiModelProperty(value = "Unique Id of the request")
     private String requestId;
 
     @ApiModelProperty(value = "List of TicketData for the requested elements. A single ticket may apply to more than 1 passed elementId.")
     private List<TicketData> elements = new ArrayList<>();
     
+    @ApiModelProperty(value = "Status of ticket request. IN_PROGRESS will indicate asynchronous processing is required.")
+    private ActiveTicketResponseStatus status;
+    @ApiModelProperty(value = "If request is asynchronous (IN_PROGRESS), suggested interval to the next poll.")
+    private Integer pollingSeconds;
+    
     public String getRequestId() {
                return requestId;
        }
@@ -70,6 +81,22 @@ public class ActiveTicketsResponse implements Serializable {
                this.elements = elements;
        }
 
+       public ActiveTicketResponseStatus getStatus() {
+               return status;
+       }
+
+       public void setStatus(ActiveTicketResponseStatus status) {
+               this.status = status;
+       }
+
+       public Integer getPollingSeconds() {
+               return pollingSeconds;
+       }
+
+       public void setPollingSeconds(Integer pollingSeconds) {
+               this.pollingSeconds = pollingSeconds;
+       }
+
        public String toString() {
         ObjectMapper mapper = new ObjectMapper();
         try {
index de09032..045d6ee 100644 (file)
@@ -5,6 +5,8 @@ CANCEL_TICKET CANCEL_TICKET|Cancel ticket {0} : {1}: {2} : {3}|No resolution nee
 UPDATE_TICKET UPDATE_TICKET|Update ticket {0} : {1}: {2} : {3}|No resolution needed|No action is required
 GET_ACTIVE_TICKETS GET_ACTIVE_TICKETS|Get active tickets {0} : {1}: {2} : {3}|No resolution needed|No action is required
 SEARCH_TICKETS SEARCH_TICKETS|Search tickets {0} : {1}: {2} : {3}|No resolution needed|No action is required
+DELETE_ACTIVE_TICKETS DELETE_ACTIVE_TICKETS|Delete active tickets {0} : {1}: {2} : {3}|No resolution needed|No action is required
+POLL_ACTIVE_TICKETS POLL_ACTIVE_TICKETS|Polling active tickets {0} : {1}: {2} : {3}|No resolution needed|No action is required
 TICKET_NOT_FOUND TICKET_NOT_FOUND|Ticket not found id={0}|No resolution needed|No action is required
 INVALID_ATTRIBUTE INVALID_ATTRIBUTE|Invalid attribute {0}={1}|No resolution needed|No action is required
 MISSING_REQUIRED_ATTRIBUTE MISSING_REQUIRED_ATTRIBUTE|Missing required attribute '{0}'|No resolution needed|No action is required