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