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