Clean up and enhancement of Actor re-design
[policy/models.git] / models-interactions / model-actors / actor.sdnc / src / main / java / org / onap / policy / controlloop / actor / sdnc / SdncOperator.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.controlloop.actor.sdnc;
22
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.concurrent.CompletableFuture;
26 import javax.ws.rs.client.Entity;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
29 import org.onap.policy.common.endpoints.http.client.HttpClient;
30 import org.onap.policy.common.utils.coder.CoderException;
31 import org.onap.policy.common.utils.coder.StandardCoder;
32 import org.onap.policy.controlloop.actorserviceprovider.AsyncResponseHandler;
33 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
34 import org.onap.policy.controlloop.actorserviceprovider.Util;
35 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
36 import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperator;
37 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
38 import org.onap.policy.controlloop.policy.PolicyResult;
39 import org.onap.policy.sdnc.SdncRequest;
40 import org.onap.policy.sdnc.SdncResponse;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 /**
45  * Superclass for SDNC Operators.
46  */
47 public abstract class SdncOperator extends HttpOperator {
48     private static final Logger logger = LoggerFactory.getLogger(SdncOperator.class);
49
50     /**
51      * Constructs the object.
52      *
53      * @param actorName name of the actor with which this operator is associated
54      * @param name operation name
55      */
56     public SdncOperator(String actorName, String name) {
57         super(actorName, name);
58     }
59
60     @Override
61     protected CompletableFuture<OperationOutcome> startOperationAsync(ControlLoopOperationParams params, int attempt,
62                     OperationOutcome outcome) {
63
64         SdncRequest request = constructRequest(params.getContext());
65         return postRequest(params, outcome, request);
66     }
67
68     /**
69      * Constructs the request.
70      *
71      * @param context associated event context
72      * @return a new request
73      */
74     protected abstract SdncRequest constructRequest(ControlLoopEventContext context);
75
76     /**
77      * Posts the request and and arranges to retrieve the response.
78      *
79      * @param params operation parameters
80      * @param outcome updated with the response
81      * @param sdncRequest request to be posted
82      * @return the result of the request
83      */
84     private CompletableFuture<OperationOutcome> postRequest(ControlLoopOperationParams params, OperationOutcome outcome,
85                     SdncRequest sdncRequest) {
86         Map<String, Object> headers = new HashMap<>();
87
88         headers.put("Accept", "application/json");
89         String sdncUrl = getClient().getBaseUrl();
90
91         Util.logRestRequest(sdncUrl, sdncRequest);
92
93         Entity<SdncRequest> entity = Entity.entity(sdncRequest, MediaType.APPLICATION_JSON);
94
95         ResponseHandler handler = new ResponseHandler(params, outcome, sdncUrl);
96         return handler.handle(getClient().post(handler, getPath(), entity, headers));
97     }
98
99     private class ResponseHandler extends AsyncResponseHandler<Response> {
100         private final String sdncUrl;
101
102         public ResponseHandler(ControlLoopOperationParams params, OperationOutcome outcome, String sdncUrl) {
103             super(params, outcome);
104             this.sdncUrl = sdncUrl;
105         }
106
107         /**
108          * Handles the response.
109          */
110         @Override
111         protected OperationOutcome doComplete(Response rawResponse) {
112             String strResponse = HttpClient.getBody(rawResponse, String.class);
113
114             Util.logRestResponse(sdncUrl, strResponse);
115
116             SdncResponse response;
117             try {
118                 response = makeDecoder().decode(strResponse, SdncResponse.class);
119             } catch (CoderException e) {
120                 logger.warn("Sdnc Heal cannot decode response with http error code {}", rawResponse.getStatus(), e);
121                 return SdncOperator.this.setOutcome(getParams(), getOutcome(), PolicyResult.FAILURE_EXCEPTION);
122             }
123
124             if (response.getResponseOutput() != null && "200".equals(response.getResponseOutput().getResponseCode())) {
125                 return SdncOperator.this.setOutcome(getParams(), getOutcome(), PolicyResult.SUCCESS);
126
127             } else {
128                 logger.info("Sdnc Heal Restcall failed with http error code {}", rawResponse.getStatus());
129                 return SdncOperator.this.setOutcome(getParams(), getOutcome(), PolicyResult.FAILURE);
130             }
131         }
132
133         /**
134          * Handles exceptions.
135          */
136         @Override
137         protected OperationOutcome doFailed(Throwable thrown) {
138             logger.info("Sdnc Heal Restcall threw an exception", thrown);
139             return SdncOperator.this.setOutcome(getParams(), getOutcome(), PolicyResult.FAILURE_EXCEPTION);
140         }
141     }
142
143     // these may be overridden by junit tests
144
145     protected StandardCoder makeDecoder() {
146         return new StandardCoder();
147     }
148 }