remove unused import classes for Ansible Adaptor
[appc.git] / appc-adapters / appc-ansible-adapter / appc-ansible-adapter-bundle / src / main / java / org / onap / appc / adapter / ansible / model / AnsibleMessageParser.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * 
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.appc.adapter.ansible.model;
26
27 /**
28  * This module imples the APP-C/Ansible Server interface
29  * based on the REST API specifications
30  */
31
32 import java.util.*;
33 import com.google.common.base.Strings;
34
35 import org.json.JSONObject;
36 import org.json.JSONArray;
37 import org.json.JSONException;
38 import org.onap.appc.exceptions.APPCException;
39 import org.onap.appc.adapter.ansible.model.AnsibleResult;
40
41
42 /**
43  * Class that validates and constructs requests sent/received from 
44  * Ansible Server
45  *
46  */
47 public class AnsibleMessageParser {
48
49
50
51
52     // Accepts a map of strings and
53     // a) validates if all parameters are appropriate (else, throws an exception)
54     // and b) if correct returns a JSON object with appropriate key-value
55     // pairs to send to the server. 
56     public JSONObject ReqMessage(Map <String, String> params) throws APPCException, NumberFormatException, JSONException{
57
58         // Mandatory  parameters, that must be in the supplied information to the Ansible Adapter
59         // 1. URL to connect to
60         // 2. credentials for URL (assume username password for now)
61         // 3. Playbook name
62         String[] mandatoryTestParams = {"AgentUrl", "PlaybookName", "User", "Password"};
63
64         // Optional testService parameters that may be provided in the request
65         String[] optionalTestParams = {"EnvParameters", "NodeList", "LocalParameters", "Timeout", "Version", "FileParameters", "Action"};
66
67         JSONObject JsonPayload = new JSONObject();
68         String payload = "";
69         JSONObject paramsJson;
70
71   
72         // Verify all the mandatory parameters are there 
73         for (String key: mandatoryTestParams){
74             if (! params.containsKey(key)){
75                 throw new APPCException(String.format("Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", key));
76             }
77             payload = params.get(key);
78             if (Strings.isNullOrEmpty(payload)){
79                 throw new APPCException(String.format("Ansible: Mandatory AnsibleAdapter key % value is Null or Emtpy", key));
80             }
81             
82             JsonPayload.put(key, payload);
83         }
84
85         // Iterate through optional parameters
86         // If null or empty omit it 
87         for (String key : optionalTestParams){
88             if (params.containsKey(key)){
89                 payload = params.get(key);
90                 if(!Strings.isNullOrEmpty(payload)){
91                     
92                     // different cases require different treatment
93                     switch (key){
94                     case "Timeout": 
95                         int Timeout = Integer.parseInt(payload);
96                         if (Timeout < 0){
97                             throw new NumberFormatException(" : specified negative integer for timeout = " +  payload);
98                         }
99                         JsonPayload.put(key, payload);
100                         break;
101
102                     case "Version": 
103                         JsonPayload.put(key, payload);
104                         break;
105
106                     case "LocalParameters":  
107                         paramsJson = new JSONObject(payload);
108                         JsonPayload.put(key, paramsJson);
109                         break;
110                         
111                     case "EnvParameters":  
112                         paramsJson = new JSONObject(payload);
113                         JsonPayload.put(key, paramsJson);
114                         break;
115                         
116                     case "NodeList":  
117                         JSONArray paramsArray = new JSONArray(payload);
118                         JsonPayload.put(key, paramsArray);
119                         break;
120                         
121                     case "FileParameters":
122                         // Files may have strings with newlines. Escape them as appropriate
123                         String formattedPayload = payload.replace("\n", "\\n").replace("\r", "\\r");
124                         JSONObject fileParams = new JSONObject(formattedPayload);
125                         JsonPayload.put(key, fileParams);
126                         break;
127                         
128                     }
129                 }
130             }
131         }
132         
133
134         // Generate a unique uuid for the test
135         String ReqId = UUID.randomUUID().toString();
136         JsonPayload.put("Id", ReqId);
137
138         return JsonPayload;
139         
140     }
141
142
143
144     // method that validates that the Map has  enough information
145     // to query Ansible server for a result . If so, it
146     // returns the appropriate url, else an empty string
147     public String ReqUri_Result(Map <String, String> params) throws APPCException, NumberFormatException{
148         
149         // Mandatory  parameters, that must be in the request
150         String[] mandatoryTestParams = {"AgentUrl", "Id", "User", "Password" };
151         
152         // Verify all the mandatory parameters are there
153         String payload = "";
154         String Uri = "";
155         
156         for (String key: mandatoryTestParams){
157             if (! params.containsKey(key)){
158                 throw new APPCException(String.format("Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", key));                
159             }
160
161             payload = params.get(key);
162             if (Strings.isNullOrEmpty(payload)){
163                 throw new APPCException(String.format("Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", key));                
164             }
165
166         }
167
168         Uri = params.get("AgentUrl") + "?Id=" + params.get("Id") + "&Type=GetResult";
169
170         return Uri;
171       
172     }
173
174
175
176     // method that validates that the Map has  enough information
177     // to query Ansible server for logs. If so, it populates the appropriate
178     // returns the appropriate url, else an empty string
179     public String ReqUri_Output(Map <String, String> params) throws APPCException, NumberFormatException{
180         
181         
182         // Mandatory  parameters, that must be in the request
183         String[] mandatoryTestParams = {"AgentUrl", "Id", "User", "Password" };
184         
185         // Verify all the mandatory parameters are there
186         String payload = "";
187         String Uri = "";
188         
189         for (String key: mandatoryTestParams){
190             if (! params.containsKey(key)){
191                 throw new APPCException(String.format("Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", key));                
192             }
193             payload = params.get(key);
194             if (Strings.isNullOrEmpty(payload)){
195                 throw new APPCException(String.format("Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", key));                
196             }
197
198         }
199
200         Uri = params.get("AgentUrl") + "?Id=" + params.get("Id") + "&Type=GetOutput";
201         return Uri;
202       
203     }
204
205     // method that validates that the Map has  enough information
206     // to query Ansible server for logs. If so, it populates the appropriate
207     // returns the appropriate url, else an empty string
208     public String ReqUri_Log(Map <String, String> params) throws APPCException, NumberFormatException{
209         
210         
211         // Mandatory  parameters, that must be in the request
212         String[] mandatoryTestParams = {"AgentUrl", "Id", "User", "Password" };
213         
214         // Verify all the mandatory parameters are there
215         String payload = "";
216         String Uri = "";
217         
218         for (String key: mandatoryTestParams){
219             if (! params.containsKey(key)){
220                 throw new APPCException(String.format("Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", key));                
221             }
222             payload = params.get(key);
223             if (Strings.isNullOrEmpty(payload)){
224                 throw new APPCException(String.format("Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", key));                
225             }
226
227         }
228
229         Uri = params.get("AgentUrl") + "?Id=" + params.get("Id") + "&Type=GetLog";
230         return Uri;
231       
232     }
233
234    
235     /** 
236         This method parses response from the 
237         Ansible Server when we do a post 
238         and returns an AnsibleResult object
239     **/
240     
241     public AnsibleResult  parsePostResponse(String Input) throws APPCException{
242
243         AnsibleResult ansibleResult = new AnsibleResult();
244         
245         try{
246             //Jsonify it
247             JSONObject  postResponse = new JSONObject(Input);
248                 
249             // Mandatory keys required are StatusCode and StatusMessage
250             int Code = postResponse.getInt("StatusCode");
251             String Message = postResponse.getString("StatusMessage");
252
253             
254             // Status code must must be either 100 (accepted) or 101 (rejected)
255             boolean valCode = AnsibleResultCodes.CODE.checkValidCode(AnsibleResultCodes.INITRESPONSE.getValue(), Code);
256             if(!valCode){
257                 throw new APPCException("Invalid InitResponse code  = " + Code + " received. MUST be one of " + AnsibleResultCodes.CODE.getValidCodes(AnsibleResultCodes.INITRESPONSE.getValue()) );
258             }
259             
260             ansibleResult.setStatusCode(Code);
261             ansibleResult.setStatusMessage(Message);
262
263         }
264         catch(JSONException e){
265             ansibleResult = new AnsibleResult(600, "Error parsing response = " + Input + ". Error = " + e.getMessage(), "");
266         }
267
268         
269         return ansibleResult;
270     }
271
272
273     /** This method  parses response from an Ansible server when we do a GET for a result 
274         and returns an AnsibleResult object
275      **/
276     public AnsibleResult  parseGetResponse(String Input) throws APPCException {
277
278         AnsibleResult ansibleResult = new AnsibleResult();
279         int FinalCode = AnsibleResultCodes.FINAL_SUCCESS.getValue();
280
281
282         try{
283             
284             //Jsonify it
285             JSONObject  postResponse = new JSONObject(Input);
286             
287             // Mandatory keys required are Status and Message
288             int Code = postResponse.getInt("StatusCode");
289             String Message = postResponse.getString("StatusMessage");
290             
291             // Status code must be valid
292             // Status code must must be either 100 (accepted) or 101 (rejected)
293             boolean valCode = AnsibleResultCodes.CODE.checkValidCode(AnsibleResultCodes.FINALRESPONSE.getValue(), Code);
294             
295             if(!valCode){
296                 throw new APPCException("Invalid FinalResponse code  = " + Code + " received. MUST be one of " + AnsibleResultCodes.CODE.getValidCodes(AnsibleResultCodes.FINALRESPONSE.getValue()));
297             }
298
299             
300             ansibleResult.setStatusCode(Code);
301             ansibleResult.setStatusMessage(Message);
302             System.out.println("Received response with code = " + Integer.toString(Code) + " Message = " + Message);
303
304             if(! postResponse.isNull("Results")){
305
306                 // Results are available. process them 
307                 // Results is a dictionary of the form
308                 // {host :{status:s, group:g, message:m, hostname:h}, ...}
309                 System.out.println("Processing results in response");
310                 JSONObject results = postResponse.getJSONObject("Results");
311                 System.out.println("Get JSON dictionary from Results ..");
312                 Iterator<String> hosts = results.keys();
313                 System.out.println("Iterating through hosts");
314                 
315                 while(hosts.hasNext()){
316                     String host = hosts.next();
317                     System.out.println("Processing host = " + host);
318                     
319                     try{
320                         JSONObject host_response = results.getJSONObject(host);
321                         int subCode = host_response.getInt("StatusCode");
322                         String message = host_response.getString("StatusMessage");
323
324                         System.out.println("Code = " + Integer.toString(subCode) + " Message = " + message);
325                         
326                         if(subCode != 200 || ! message.equals("SUCCESS")){
327                             FinalCode = AnsibleResultCodes.REQ_FAILURE.getValue();
328                         }
329                     }
330                     catch(JSONException e){
331                         ansibleResult.setStatusCode(AnsibleResultCodes.INVALID_RESPONSE.getValue());
332                         ansibleResult.setStatusMessage(String.format("Error processing response message = %s from host %s", results.getString(host), host));
333                         break;
334                     }
335                 }
336
337                 ansibleResult.setStatusCode(FinalCode);
338
339                 // We return entire Results object as message
340                 ansibleResult.setResults(results.toString());
341
342             }
343             else{
344                 ansibleResult.setStatusCode(AnsibleResultCodes.INVALID_RESPONSE.getValue());
345                 ansibleResult.setStatusMessage("Results not found in GET for response");
346             }
347             
348             
349         }
350         catch(JSONException e){
351             ansibleResult = new AnsibleResult(AnsibleResultCodes.INVALID_PAYLOAD.getValue(), "Error parsing response = " + Input + ". Error = " + e.getMessage(), "");
352         }
353
354
355         return ansibleResult;
356     }
357
358
359
360 };    
361             
362             
363