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