Merge "Fix for HAS to run its CSIT"
[music.git] / src / main / java / org / onap / music / rest / RestMusicLocksAPI.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 import java.util.Map;
25
26 import javax.servlet.http.HttpServletResponse;
27 import javax.ws.rs.Consumes;
28 import javax.ws.rs.DELETE;
29 import javax.ws.rs.GET;
30 import javax.ws.rs.HeaderParam;
31 import javax.ws.rs.POST;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.PathParam;
34 import javax.ws.rs.Produces;
35 import javax.ws.rs.core.Context;
36 import javax.ws.rs.core.MediaType;
37
38 import org.onap.music.datastore.jsonobjects.JsonLeasedLock;
39 import org.onap.music.eelf.logging.EELFLoggerDelegate;
40 import org.onap.music.eelf.logging.format.AppMessages;
41 import org.onap.music.eelf.logging.format.ErrorSeverity;
42 import org.onap.music.eelf.logging.format.ErrorTypes;
43 import org.onap.music.lockingservice.MusicLockState;
44 import org.onap.music.main.MusicCore;
45 import org.onap.music.main.MusicUtil;
46 import org.onap.music.main.ResultType;
47 import org.onap.music.main.ReturnType;
48 import org.onap.music.response.jsonobjects.JsonResponse;
49
50 import io.swagger.annotations.Api;
51 import io.swagger.annotations.ApiOperation;
52 import io.swagger.annotations.ApiParam;
53
54
55 @Path("/v{version: [0-9]+}/locks/")
56 @Api(value="Lock Api")
57 public class RestMusicLocksAPI {
58
59         @SuppressWarnings("unused")
60     private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicLocksAPI.class);
61         private static String xLatestVersion = "X-latestVersion";
62
63         /**
64          * Puts the requesting process in the q for this lock. The corresponding
65          * node will be created in zookeeper if it did not already exist
66          * 
67          * @param lockName
68          * @return
69          * @throws Exception 
70          */
71
72         @POST
73         @Path("/create/{lockname}")
74         @ApiOperation(value = "Create Lock",
75                 notes = "Puts the requesting process in the q for this lock." +
76                 " The corresponding node will be created in zookeeper if it did not already exist." +
77                 " Lock Name is the \"key\" of the form keyspaceName.tableName.rowId",
78                 response = Map.class)
79         @Produces(MediaType.APPLICATION_JSON)   
80         public Map<String,Object> createLockReference(
81                         @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
82                         @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
83             @ApiParam(value = "Application namespace",
84                             required = true) @HeaderParam("ns") String ns,
85             @ApiParam(value = "userId",
86                             required = true) @HeaderParam("userId") String userId,
87             @ApiParam(value = "Password",
88                             required = true) @HeaderParam("password") String password,
89                         @Context HttpServletResponse response) throws Exception{
90                 response.addHeader(xLatestVersion,MusicUtil.getVersion());      
91         Map<String, Object> resultMap = MusicCore.validateLock(lockName);
92         if (resultMap.containsKey("Exception")) {
93                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
94             response.setStatus(400);
95             return resultMap;
96         }
97         String keyspaceName = (String) resultMap.get("keyspace");
98         resultMap.remove("keyspace");
99         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
100                 "createLockReference");
101         if (resultMap.containsKey("aid"))
102             resultMap.remove("aid");
103         if (!resultMap.isEmpty()) {
104                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO  ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
105             response.setStatus(401);
106             return resultMap;
107         }
108                 ResultType status = ResultType.SUCCESS;
109                 String lockId = MusicCore.createLockReference(lockName);
110                 
111                 if (lockId == null) { 
112                         status = ResultType.FAILURE; 
113                         logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR  ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
114             response.setStatus(400);
115             return new JsonResponse(status).setError("Lock Id is null").toMap();
116                 }
117                 return new JsonResponse(status).setLock(lockId).toMap();
118         }
119
120         /**
121          * 
122          * Checks if the node is in the top of the queue and hence acquires the lock
123          * 
124          * @param lockId
125          * @return
126          * @throws Exception 
127          */
128         @GET
129         @Path("/acquire/{lockreference}")
130         @ApiOperation(value = "Aquire Lock", 
131                 notes = "Checks if the node is in the top of the queue and hence acquires the lock",
132                 response = Map.class)
133         @Produces(MediaType.APPLICATION_JSON)   
134         public Map<String,Object> accquireLock(
135                         @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId,
136                         @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
137             @ApiParam(value = "Application namespace",
138                             required = true) @HeaderParam("ns") String ns,
139             @ApiParam(value = "userId",
140                             required = true) @HeaderParam("userId") String userId,
141             @ApiParam(value = "Password",
142                             required = true) @HeaderParam("password") String password,
143                         @Context HttpServletResponse response) throws Exception{
144                 response.addHeader(xLatestVersion,MusicUtil.getVersion());
145         Map<String, Object> resultMap = MusicCore.validateLock(lockId);
146         if (resultMap.containsKey("Exception")) {
147                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
148             response.setStatus(400);
149             return resultMap;
150         }
151         String keyspaceName = (String) resultMap.get("keyspace");
152         resultMap.remove("keyspace");
153         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
154                 "accquireLock");
155         if (resultMap.containsKey("aid"))
156             resultMap.remove("aid");
157         if (!resultMap.isEmpty()) {
158                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
159             response.setStatus(400);
160             return resultMap;
161         }
162                 try {
163                         String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
164                         ReturnType lockStatus = MusicCore.acquireLock(lockName,lockId);
165                         return new JsonResponse(lockStatus.getResult()).setLock(lockId)
166                                                                                 .setMessage(lockStatus.getMessage()).toMap();
167                 } catch (Exception e) {
168                         logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId, ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
169                         resultMap.put("Exception","Unable to aquire lock");
170                         response.setStatus(400);
171                         return new JsonResponse(ResultType.FAILURE).setError("Unable to aquire lock").toMap();
172                 }
173         }
174         
175
176
177         
178         @POST
179         @Path("/acquire-with-lease/{lockreference}")
180         @ApiOperation(value = "Aquire Lock with Lease", response = Map.class)
181         @Consumes(MediaType.APPLICATION_JSON)
182         @Produces(MediaType.APPLICATION_JSON)   
183         public Map<String,Object> accquireLockWithLease(JsonLeasedLock lockObj, 
184                         @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId,
185                         @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
186             @ApiParam(value = "Application namespace",
187                             required = true) @HeaderParam("ns") String ns,
188             @ApiParam(value = "userId",
189                             required = true) @HeaderParam("userId") String userId,
190             @ApiParam(value = "Password",
191                             required = true) @HeaderParam("password") String password,
192                         @Context HttpServletResponse response) throws Exception{
193                 response.addHeader(xLatestVersion,MusicUtil.getVersion());
194         Map<String, Object> resultMap = MusicCore.validateLock(lockId);
195         if (resultMap.containsKey("Exception")) {
196                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
197             response.setStatus(400);
198             return resultMap;
199         }
200         String keyspaceName = (String) resultMap.get("keyspace");
201         resultMap.remove("keyspace");
202         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
203                 "accquireLockWithLease");
204
205         if (resultMap.containsKey("aid"))
206             resultMap.remove("aid");
207         if (!resultMap.isEmpty()) {
208                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
209             response.setStatus(400);    
210                 return resultMap;
211         }
212                 String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
213                 ReturnType lockLeaseStatus = MusicCore.acquireLockWithLease(lockName, lockId, lockObj.getLeasePeriod());
214                 return new JsonResponse(lockLeaseStatus.getResult()).setLock(lockName)
215                                                                         .setMessage(lockLeaseStatus.getMessage())
216                                                                         .setLockLease(String.valueOf(lockObj.getLeasePeriod())).toMap();
217         } 
218         
219
220         @GET
221         @Path("/enquire/{lockname}")
222         @ApiOperation(value = "Get Lock Holder", 
223                 notes = "Gets the current Lock Holder",
224                 response = Map.class)
225         @Produces(MediaType.APPLICATION_JSON)   
226         public Map<String,Object> currentLockHolder(
227                         @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
228                         @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
229             @ApiParam(value = "Application namespace",
230                             required = true) @HeaderParam("ns") String ns,
231             @ApiParam(value = "userId",
232                             required = true) @HeaderParam("userId") String userId,
233             @ApiParam(value = "Password",
234                             required = true) @HeaderParam("password") String password,
235                         @Context HttpServletResponse response) throws Exception{
236                 response.addHeader(xLatestVersion,MusicUtil.getVersion());
237         Map<String, Object> resultMap = MusicCore.validateLock(lockName);
238         if (resultMap.containsKey("Exception")) {
239                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
240             response.setStatus(400);
241             return resultMap;
242         }
243         String keyspaceName = (String) resultMap.get("keyspace");
244         resultMap.remove("keyspace");
245         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
246                 "currentLockHolder");
247         if (resultMap.containsKey("aid"))
248             resultMap.remove("aid");
249         if (!resultMap.isEmpty()) {
250                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
251             response.setStatus(400);
252             return resultMap;
253         }
254                 String who = MusicCore.whoseTurnIsIt(lockName);
255                 ResultType status = ResultType.SUCCESS;
256                 String error = "";
257                 if ( who == null ) { 
258                         status = ResultType.FAILURE; 
259                         error = "There was a problem getting the lock holder";
260                         logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
261             response.setStatus(400);
262             return new JsonResponse(status).setError(error)
263                                         .setLock(lockName).setLockHolder(who).toMap();
264                 }
265                 return new JsonResponse(status).setError(error)
266                                                 .setLock(lockName).setLockHolder(who).toMap();
267         }
268
269         @GET
270         @Path("/{lockname}")
271         @ApiOperation(value = "Lock State",
272                 notes = "Returns current Lock State and Holder.",
273                 response = Map.class)
274         @Produces(MediaType.APPLICATION_JSON)   
275         public Map<String,Object> currentLockState(
276                         @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
277                         @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
278             @ApiParam(value = "Application namespace",
279                             required = true) @HeaderParam("ns") String ns,
280             @ApiParam(value = "userId",
281                             required = true) @HeaderParam("userId") String userId,
282             @ApiParam(value = "Password",
283                             required = true) @HeaderParam("password") String password,
284                         @Context HttpServletResponse response) throws Exception{
285                 response.addHeader(xLatestVersion,MusicUtil.getVersion());
286         Map<String, Object> resultMap = MusicCore.validateLock(lockName);
287         if (resultMap.containsKey("Exception")) {
288                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
289             response.setStatus(400);
290             return resultMap;
291         }
292         String keyspaceName = (String) resultMap.get("keyspace");
293         resultMap.remove("keyspace");
294         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
295                 "currentLockState");
296         
297         if (resultMap.containsKey("aid"))
298             resultMap.remove("aid");
299         if (!resultMap.isEmpty()) {
300                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
301             response.setStatus(400);
302                 return resultMap;
303         }
304                 
305         MusicLockState mls = MusicCore.getMusicLockState(lockName);
306                 Map<String,Object> returnMap = null;
307                 JsonResponse jsonResponse = new JsonResponse(ResultType.FAILURE).setLock(lockName);
308                 if(mls == null) {
309                         jsonResponse.setError("");
310                         jsonResponse.setMessage("No lock object created yet..");
311                         logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
312             response.setStatus(400);
313             return jsonResponse.toMap();
314                 } else { 
315                         jsonResponse.setStatus(ResultType.SUCCESS);
316                         jsonResponse.setLockStatus(mls.getLockStatus());
317                         jsonResponse.setLockHolder(mls.getLockHolder());
318                         return jsonResponse.toMap();
319                 } 
320         }
321
322         /**
323          * 
324          * deletes the process from the zk queue
325          * 
326          * @param lockId
327          * @throws Exception 
328          */
329         @DELETE
330         @Path("/release/{lockreference}")
331         @ApiOperation(value = "Release Lock",
332                 notes = "deletes the process from the zk queue",
333                 response = Map.class)
334         @Produces(MediaType.APPLICATION_JSON)   
335         public Map<String,Object> unLock(@PathParam("lockreference") String lockId,
336                         @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
337             @ApiParam(value = "Application namespace",
338                             required = true) @HeaderParam("ns") String ns,
339             @ApiParam(value = "userId",
340                             required = true) @HeaderParam("userId") String userId,
341             @ApiParam(value = "Password",
342                             required = true) @HeaderParam("password") String password,
343                         @Context HttpServletResponse response) throws Exception{
344                 response.addHeader(xLatestVersion,MusicUtil.getVersion());
345         Map<String, Object> resultMap = MusicCore.validateLock(lockId);
346         if (resultMap.containsKey("Exception")) {
347                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
348             response.setStatus(400);
349             return resultMap;
350         }
351         String keyspaceName = (String) resultMap.get("keyspace");
352         resultMap.remove("keyspace");
353         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
354                 "unLock");
355         if (resultMap.containsKey("aid"))
356             resultMap.remove("aid");
357         if (!resultMap.isEmpty()) {
358                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
359             response.setStatus(400);
360             return resultMap;
361         }
362                 boolean voluntaryRelease = true; 
363                 MusicLockState mls = MusicCore.releaseLock(lockId,voluntaryRelease);
364                 if(mls.getErrorMessage() != null) {
365                         resultMap.put(ResultType.EXCEPTION.getResult(), mls.getErrorMessage());
366                         logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
367             response.setStatus(400);
368                         return resultMap;
369                 }
370                 Map<String,Object> returnMap = null;
371                 if (mls.getLockStatus() == MusicLockState.LockStatus.UNLOCKED) {
372                         returnMap = new JsonResponse(ResultType.SUCCESS).setLock(lockId)
373                                                                 .setLockStatus(mls.getLockStatus()).toMap();
374                 }
375                 if (mls.getLockStatus() == MusicLockState.LockStatus.LOCKED) {
376                         logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
377             response.setStatus(400);
378                         returnMap = new JsonResponse(ResultType.FAILURE).setLock(lockId)
379                                                                 .setLockStatus(mls.getLockStatus()).toMap();
380                 }
381                 return returnMap;
382         }
383
384         /**
385          * 
386          * @param lockName
387          * @throws Exception 
388          */
389         @DELETE
390         @Path("/delete/{lockname}")
391         @ApiOperation(value = "Delete Lock", response = Map.class)
392         @Produces(MediaType.APPLICATION_JSON)   
393         public Map<String,Object> deleteLock(@PathParam("lockname") String lockName,
394                         @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
395             @ApiParam(value = "Application namespace",
396                             required = true) @HeaderParam("ns") String ns,
397             @ApiParam(value = "userId",
398                             required = true) @HeaderParam("userId") String userId,
399             @ApiParam(value = "Password",
400                             required = true) @HeaderParam("password") String password,
401                         @Context HttpServletResponse response) throws Exception{
402                 response.addHeader(xLatestVersion,MusicUtil.getVersion());
403         Map<String, Object> resultMap = MusicCore.validateLock(lockName);
404         if (resultMap.containsKey("Exception")) {
405                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
406             response.setStatus(400);
407             return resultMap;
408         }
409         String keyspaceName = (String) resultMap.get("keyspace");
410         resultMap.remove("keyspace");
411         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
412                 "deleteLock");
413         if (resultMap.containsKey("aid"))
414             resultMap.remove("aid");
415         if (!resultMap.isEmpty()) {
416                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR  ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
417             response.setStatus(400);
418                 return resultMap;
419         }
420                 MusicCore.deleteLock(lockName);
421                 return new JsonResponse(ResultType.SUCCESS).toMap();
422         }
423
424 }