various Updates
[music.git] / src / main / java / org / onap / music / rest / RestMusicAdminAPI.java
1 /*
2  * ============LICENSE_START==========================================
3  * org.onap.music
4  * ===================================================================
5  *  Copyright (c) 2017 AT&T Intellectual Property
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  * 
19  * ============LICENSE_END=============================================
20  * ====================================================================
21  */
22 package org.onap.music.rest;
23
24
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.UUID;
30 import javax.ws.rs.Consumes;
31 import javax.ws.rs.DELETE;
32 import javax.ws.rs.POST;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.Produces;
36 import javax.ws.rs.core.MediaType;
37 import javax.ws.rs.core.Response;
38 import javax.ws.rs.core.Response.ResponseBuilder;
39 import javax.ws.rs.core.Response.Status;
40
41 import org.mindrot.jbcrypt.BCrypt;
42 import org.onap.music.datastore.PreparedQueryObject;
43 import org.onap.music.datastore.jsonobjects.JSONObject;
44 import org.onap.music.datastore.jsonobjects.JsonOnboard;
45 import org.onap.music.eelf.logging.EELFLoggerDelegate;
46 import org.onap.music.eelf.logging.format.AppMessages;
47 import org.onap.music.eelf.logging.format.ErrorSeverity;
48 import org.onap.music.eelf.logging.format.ErrorTypes;
49 import org.onap.music.main.CachingUtil;
50 import org.onap.music.main.MusicCore;
51 import org.onap.music.main.MusicUtil;
52 import org.onap.music.main.ResultType;
53 import com.datastax.driver.core.DataType;
54 import com.datastax.driver.core.ResultSet;
55 import com.datastax.driver.core.Row;
56 import io.swagger.annotations.Api;
57 import io.swagger.annotations.ApiOperation;
58
59 @Path("/v2/admin")
60 // @Path("/v{version: [0-9]+}/admin")
61 // @Path("/admin")
62 @Api(value = "Admin Api", hidden = true)
63 public class RestMusicAdminAPI {
64     private static EELFLoggerDelegate logger =
65                     EELFLoggerDelegate.getLogger(RestMusicAdminAPI.class);
66
67     /*
68      * API to onboard an application with MUSIC. This is the mandatory first step.
69      * 
70      */
71     @POST
72     @Path("/onboardAppWithMusic")
73     @ApiOperation(value = "Onboard application", response = String.class)
74     @Consumes(MediaType.APPLICATION_JSON)
75     @Produces(MediaType.APPLICATION_JSON)
76     public Response onboardAppWithMusic(JsonOnboard jsonObj) throws Exception {
77         ResponseBuilder response =
78                         Response.noContent().header("X-latestVersion", MusicUtil.getVersion());
79         Map<String, Object> resultMap = new HashMap<>();
80         String appName = jsonObj.getAppname();
81         String userId = jsonObj.getUserId();
82         String isAAF = jsonObj.getIsAAF();
83         String password = jsonObj.getPassword();
84         if (appName == null || userId == null || isAAF == null || password == null) {
85             logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO,
86                             ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
87             resultMap.put("Exception",
88                             "Unauthorized: Please check the request parameters. Some of the required values appName(ns), userId, password, isAAF are missing.");
89             return Response.status(Status.UNAUTHORIZED).entity(resultMap).build();
90         }
91
92         PreparedQueryObject pQuery = new PreparedQueryObject();
93         pQuery.appendQueryString(
94                         "select uuid from admin.keyspace_master where application_name = ? allow filtering");
95         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
96         ResultSet rs = MusicCore.get(pQuery);
97         if (!rs.all().isEmpty()) {
98             resultMap.put("Exception", "Application " + appName
99                             + " has already been onboarded. Please contact admin.");
100             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
101         }
102
103         pQuery = new PreparedQueryObject();
104         String uuid = CachingUtil.generateUUID();
105         pQuery.appendQueryString(
106                         "INSERT INTO admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
107                                         + "password, username, is_aaf) VALUES (?,?,?,?,?,?,?)");
108         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
109         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
110                         MusicUtil.DEFAULTKEYSPACENAME));
111         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
112         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
113         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt())));
114         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
115         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
116
117         String returnStr = MusicCore.eventualPut(pQuery).toString();
118         if (returnStr.contains("Failure")) {
119             resultMap.put("Exception",
120                             "Oops. Something wrong with onboarding process. Please retry later or contact admin.");
121             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
122         }
123         CachingUtil.updateisAAFCache(appName, isAAF);
124         resultMap.put("Success", "Your application " + appName + " has been onboarded with MUSIC.");
125         resultMap.put("Generated AID", uuid);
126         return Response.status(Status.OK).entity(resultMap).build();
127     }
128
129
130     @POST
131     @Path("/search")
132     @ApiOperation(value = "Search Onboard application", response = String.class)
133     @Consumes(MediaType.APPLICATION_JSON)
134     @Produces(MediaType.APPLICATION_JSON)
135     public Response getOnboardedInfoSearch(JsonOnboard jsonObj) throws Exception {
136         Map<String, Object> resultMap = new HashMap<>();
137         ResponseBuilder response =
138                         Response.noContent().header("X-latestVersion", MusicUtil.getVersion());
139         String appName = jsonObj.getAppname();
140         String uuid = jsonObj.getAid();
141         String isAAF = jsonObj.getIsAAF();
142
143         if (appName == null && uuid == null && isAAF == null) {
144             logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO,
145                             ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
146             resultMap.put("Exception",
147                             "Unauthorized: Please check the request parameters. Enter atleast one of the following parameters: appName(ns), aid, isAAF.");
148             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
149         }
150
151         PreparedQueryObject pQuery = new PreparedQueryObject();
152         String cql = "select uuid, keyspace_name from admin.keyspace_master where ";
153         if (appName != null)
154             cql = cql + "application_name = ? AND ";
155         if (uuid != null)
156             cql = cql + "uuid = ? AND ";
157         if (isAAF != null)
158             cql = cql + "is_aaf = ?";
159
160         if (cql.endsWith("AND "))
161             cql = cql.trim().substring(0, cql.length() - 4);
162         System.out.println("Query is: " + cql);
163         cql = cql + " allow filtering";
164         System.out.println("Get OnboardingInfo CQL: " + cql);
165         pQuery.appendQueryString(cql);
166         if (appName != null)
167             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
168         if (uuid != null)
169             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
170         if (isAAF != null)
171             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(),
172                             Boolean.parseBoolean(isAAF)));
173         ResultSet rs = MusicCore.get(pQuery);
174         Iterator<Row> it = rs.iterator();
175         while (it.hasNext()) {
176             Row row = (Row) it.next();
177             resultMap.put(row.getUUID("uuid").toString(), row.getString("keyspace_name"));
178         }
179         if (resultMap.isEmpty()) {
180             if (uuid != null) {
181                 resultMap.put("Exception",
182                                 "Please make sure Aid is correct and application is onboarded.");
183                 return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
184             } else {
185                 resultMap.put("Exception",
186                                 "Application is not onboarded. Please make sure all the information is correct.");
187                 return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
188             }
189         }
190         return Response.status(Status.OK).entity(resultMap).build();
191     }
192
193
194     @DELETE
195     @Path("/onboardAppWithMusic")
196     @ApiOperation(value = "Delete Onboard application", response = String.class)
197     @Consumes(MediaType.APPLICATION_JSON)
198     @Produces(MediaType.APPLICATION_JSON)
199     public Response deleteOnboardApp(JsonOnboard jsonObj) throws Exception {
200         Map<String, Object> resultMap = new HashMap<>();
201         ResponseBuilder response =
202                         Response.noContent().header("X-latestVersion", MusicUtil.getVersion());
203         String appName = jsonObj.getAppname();
204         String aid = jsonObj.getAid();
205         PreparedQueryObject pQuery = new PreparedQueryObject();
206         String consistency = MusicUtil.EVENTUAL;;
207         if (appName == null && aid == null) {
208             logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO,
209                             ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
210             resultMap.put("Exception", "Please make sure either appName(ns) or Aid is present");
211             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
212         }
213         if (aid != null) {
214             pQuery.appendQueryString(
215                             "SELECT keyspace_name FROM admin.keyspace_master WHERE uuid = ?");
216             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),
217                             UUID.fromString(aid)));
218             Row row = MusicCore.get(pQuery).one();
219             if (row != null) {
220                 String ks = row.getString("keyspace_name");
221                 if (!ks.equals(MusicUtil.DEFAULTKEYSPACENAME)) {
222                     PreparedQueryObject queryObject = new PreparedQueryObject();
223                     queryObject.appendQueryString("DROP KEYSPACE IF EXISTS " + ks + ";");
224                     MusicCore.nonKeyRelatedPut(queryObject, consistency);
225                 }
226             }
227             pQuery = new PreparedQueryObject();
228             pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ? IF EXISTS");
229             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),
230                             UUID.fromString(aid)));
231             ResultType result = MusicCore.nonKeyRelatedPut(pQuery, consistency);
232             if (result == ResultType.SUCCESS) {
233                 resultMap.put("Success", "Your application has been deleted successfully");
234             } else {
235                 resultMap.put("Exception",
236                                 "Oops. Something went wrong. Please make sure Aid is correct or Application is onboarded");
237                 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA,
238                                 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
239                 return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
240
241             }
242             return Response.status(Status.OK).entity(resultMap).build();
243         }
244
245         pQuery.appendQueryString(
246                         "select uuid from admin.keyspace_master where application_name = ? allow filtering");
247         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
248         ResultSet rs = MusicCore.get(pQuery);
249         List<Row> rows = rs.all();
250         String uuid = null;
251         if (rows.size() == 0) {
252             resultMap.put("Exception",
253                             "Application not found. Please make sure Application exists.");
254             logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA,
255                             ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
256             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
257         } else if (rows.size() == 1) {
258             uuid = rows.get(0).getUUID("uuid").toString();
259             pQuery = new PreparedQueryObject();
260             pQuery.appendQueryString(
261                             "SELECT keyspace_name FROM admin.keyspace_master WHERE uuid = ?");
262             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),
263                             UUID.fromString(uuid)));
264             Row row = MusicCore.get(pQuery).one();
265             String ks = row.getString("keyspace_name");
266             if (!ks.equals(MusicUtil.DEFAULTKEYSPACENAME)) {
267                 PreparedQueryObject queryObject = new PreparedQueryObject();
268                 queryObject.appendQueryString("DROP KEYSPACE " + ks + ";");
269                 MusicCore.nonKeyRelatedPut(queryObject, consistency);
270             }
271
272             pQuery = new PreparedQueryObject();
273             pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
274             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),
275                             UUID.fromString(uuid)));
276             MusicCore.eventualPut(pQuery);
277             resultMap.put("Success", "Your application " + appName + " has been deleted.");
278             return Response.status(Status.OK).entity(resultMap).build();
279         } else {
280             resultMap.put("Failure",
281                             "More than one Aid exists for this application, so please provide Aid.");
282             logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MULTIPLERECORDS,
283                             ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
284             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
285         }
286     }
287
288
289     @PUT
290     @Path("/onboardAppWithMusic")
291     @ApiOperation(value = "Update Onboard application", response = String.class)
292     @Consumes(MediaType.APPLICATION_JSON)
293     @Produces(MediaType.APPLICATION_JSON)
294     public Response updateOnboardApp(JsonOnboard jsonObj) throws Exception {
295         Map<String, Object> resultMap = new HashMap<>();
296         ResponseBuilder response =
297                         Response.noContent().header("X-latestVersion", MusicUtil.getVersion());
298         String aid = jsonObj.getAid();
299         String appName = jsonObj.getAppname();
300         String userId = jsonObj.getUserId();
301         String isAAF = jsonObj.getIsAAF();
302         String password = jsonObj.getPassword();
303         String consistency = "eventual";
304         PreparedQueryObject pQuery;
305
306         if (aid == null) {
307             resultMap.put("Exception", "Please make sure Aid is present");
308             logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
309                             ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
310             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
311         }
312
313         if (appName == null && userId == null && password == null && isAAF == null) {
314             resultMap.put("Exception",
315                             "No parameters found to update. Please update atleast one parameter.");
316             logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
317                             ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
318             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
319         }
320
321         if (appName != null) {
322             pQuery = new PreparedQueryObject();
323             pQuery.appendQueryString(
324                             "select uuid from admin.keyspace_master where application_name = ? allow filtering");
325             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
326             ResultSet rs = MusicCore.get(pQuery);
327             if (!rs.all().isEmpty()) {
328                 resultMap.put("Exception", "Application " + appName
329                                 + " has already been onboarded. Please contact admin.");
330                 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.ALREADYEXIST,
331                                 ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
332                 return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
333             }
334         }
335
336         pQuery = new PreparedQueryObject();
337         StringBuilder preCql = new StringBuilder("UPDATE admin.keyspace_master SET ");
338         if (appName != null)
339             preCql.append(" application_name = ?,");
340         if (userId != null)
341             preCql.append(" username = ?,");
342         if (password != null)
343             preCql.append(" password = ?,");
344         if (isAAF != null)
345             preCql.append(" is_aaf = ?,");
346         preCql.deleteCharAt(preCql.length() - 1);
347         preCql.append(" WHERE uuid = ? IF EXISTS");
348         pQuery.appendQueryString(preCql.toString());
349         if (appName != null)
350             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
351         if (userId != null)
352             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
353         if (password != null)
354             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt())));
355         if (isAAF != null)
356             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
357
358         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), UUID.fromString(aid)));
359         ResultType result = MusicCore.nonKeyRelatedPut(pQuery, consistency);
360
361         if (result == ResultType.SUCCESS) {
362             resultMap.put("Success", "Your application has been updated successfully");
363         } else {
364             resultMap.put("Exception",
365                             "Oops. Something went wrong. Please make sure Aid is correct and application is onboarded");
366             logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA,
367                             ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
368             return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
369         }
370
371         return Response.status(Status.OK).entity(resultMap).build();
372     }
373     
374     @POST
375     @Path("/callbackOps")
376     @Produces(MediaType.APPLICATION_JSON)
377     @Consumes(MediaType.APPLICATION_JSON)
378     public String callbackOps(JSONObject inputJsonObj) throws Exception {
379        
380        System.out.println("Input JSON: "+inputJsonObj.getData());
381        return "Success";
382     }
383 }