2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (c) 2017 AT&T Intellectual Property
6 * ===================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ===================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * ============LICENSE_END=============================================
22 * ====================================================================
25 package org.onap.music.rest;
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.HeaderParam;
33 import javax.ws.rs.POST;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.core.MediaType;
38 import javax.ws.rs.core.Response;
39 import javax.ws.rs.core.Response.ResponseBuilder;
40 import javax.ws.rs.core.Response.Status;
42 import org.onap.music.authentication.MusicAAFAuthentication;
43 import org.onap.music.authentication.MusicAuthenticator;
44 import org.onap.music.authentication.MusicAuthenticator.Operation;
45 import org.onap.music.datastore.jsonobjects.JsonLeasedLock;
46 import org.onap.music.eelf.logging.EELFLoggerDelegate;
47 import org.onap.music.eelf.logging.format.AppMessages;
48 import org.onap.music.eelf.logging.format.ErrorSeverity;
49 import org.onap.music.eelf.logging.format.ErrorTypes;
50 import org.onap.music.lockingservice.cassandra.MusicLockState;
51 import org.onap.music.main.MusicCore;
52 import org.onap.music.main.MusicUtil;
53 import org.onap.music.main.ResultType;
54 import org.onap.music.main.ReturnType;
55 import org.onap.music.response.jsonobjects.JsonResponse;
57 import io.swagger.annotations.Api;
58 import io.swagger.annotations.ApiOperation;
59 import io.swagger.annotations.ApiParam;
63 @Api(value="Lock Api")
64 public class RestMusicLocksAPI {
66 private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicLocksAPI.class);
67 private static final String XMINORVERSION = "X-minorVersion";
68 private static final String XPATCHVERSION = "X-patchVersion";
69 private static final String VERSION = "v2";
71 private MusicAuthenticator authenticator = new MusicAAFAuthentication();
74 * Puts the requesting process in the q for this lock. The corresponding
75 * node will be created if it did not already exist
82 @Path("/create/{lockname}")
83 @ApiOperation(value = "Create Lock",
84 notes = "Puts the requesting process in the q for this lock." +
85 " The corresponding lock will be created if it did not already exist." +
86 " Lock Name is the \"key\" of the form keyspaceName.tableName.rowId",
88 @Produces(MediaType.APPLICATION_JSON)
89 public Response createLockReference(
90 @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
91 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
92 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
93 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
94 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
95 @ApiParam(value = "Application namespace",
96 required = true) @HeaderParam("ns") String ns) throws Exception{
98 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
99 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
100 if (resultMap.containsKey("Error")) {
101 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
102 response.status(Status.BAD_REQUEST);
103 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
105 String keyspaceName = (String) resultMap.get("keyspace");
106 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
108 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CREATE_LOCKREF)) {
109 return response.status(Status.UNAUTHORIZED)
110 .entity(new JsonResponse(ResultType.FAILURE)
111 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
115 ResultType status = ResultType.SUCCESS;
116 String lockId = MusicCore.createLockReference(lockName);
118 if (lockId == null) {
119 status = ResultType.FAILURE;
120 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
121 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError("Lock Id is null").toMap()).build();
123 return response.status(Status.OK).entity(new JsonResponse(status).setLock(lockId).toMap()).build();
125 EELFLoggerDelegate.mdcRemove("keyspace");
131 * Checks if the node is in the top of the queue and hence acquires the lock
138 @Path("/acquire/{lockreference}")
139 @ApiOperation(value = "Aquire Lock",
140 notes = "Checks if the node is in the top of the queue and hence acquires the lock",
141 response = Map.class)
142 @Produces(MediaType.APPLICATION_JSON)
143 public Response accquireLock(
144 @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId,
145 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
146 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
147 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
148 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
149 @ApiParam(value = "Application namespace",
150 required = true) @HeaderParam("ns") String ns) throws Exception{
152 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
153 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
154 if (resultMap.containsKey("Error")) {
155 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
156 response.status(Status.BAD_REQUEST);
157 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
160 String keyspaceName = (String) resultMap.get("keyspace");
161 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
163 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.ACQUIRE_LOCK)) {
164 return response.status(Status.UNAUTHORIZED)
165 .entity(new JsonResponse(ResultType.FAILURE)
166 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
171 String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
172 ReturnType lockStatus = MusicCore.acquireLock(lockName,lockId);
173 if ( lockStatus.getResult().equals(ResultType.SUCCESS)) {
174 response.status(Status.OK);
176 response.status(Status.BAD_REQUEST);
178 return response.entity(new JsonResponse(lockStatus.getResult()).setLock(lockId).setMessage(lockStatus.getMessage()).toMap()).build();
179 } catch (Exception e) {
180 logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId, ErrorSeverity.CRITICAL,
181 ErrorTypes.LOCKINGERROR, e);
182 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Unable to aquire lock").toMap()).build();
185 EELFLoggerDelegate.mdcRemove("keyspace");
193 @Path("/acquire-with-lease/{lockreference}")
194 @ApiOperation(value = "Aquire Lock with Lease", response = Map.class)
195 @Consumes(MediaType.APPLICATION_JSON)
196 @Produces(MediaType.APPLICATION_JSON)
197 public Response accquireLockWithLease(JsonLeasedLock lockObj,
198 @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId,
199 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
200 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
201 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
202 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
203 @ApiParam(value = "Application namespace",
204 required = true) @HeaderParam("ns") String ns) throws Exception{
206 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
207 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
208 if (resultMap.containsKey("Error")) {
209 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
210 response.status(Status.BAD_REQUEST);
211 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
213 String keyspaceName = (String) resultMap.get("keyspace");
214 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
215 resultMap.remove("keyspace");
216 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.ACQUIRE_LOCK)) {
217 return response.status(Status.UNAUTHORIZED)
218 .entity(new JsonResponse(ResultType.FAILURE)
219 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
223 String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
224 ReturnType lockLeaseStatus = MusicCore.acquireLockWithLease(lockName, lockId, lockObj.getLeasePeriod());
225 if ( lockLeaseStatus.getResult().equals(ResultType.SUCCESS)) {
226 response.status(Status.OK);
228 response.status(Status.BAD_REQUEST);
230 return response.entity(new JsonResponse(lockLeaseStatus.getResult()).setLock(lockName)
231 .setMessage(lockLeaseStatus.getMessage())
232 .setLockLease(String.valueOf(lockObj.getLeasePeriod())).toMap()).build();
234 EELFLoggerDelegate.mdcRemove("keyspace");
240 @Path("/enquire/{lockname}")
241 @ApiOperation(value = "Get Lock Holder",
242 notes = "Gets the current Lock Holder",
243 response = Map.class)
244 @Produces(MediaType.APPLICATION_JSON)
245 public Response currentLockHolder(
246 @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
247 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
248 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
249 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
250 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
251 @ApiParam(value = "Application namespace",
252 required = true) @HeaderParam("ns") String ns) throws Exception{
254 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
255 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
256 if (resultMap.containsKey("Error")) {
257 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
258 response.status(Status.BAD_REQUEST);
259 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
262 String keyspaceName = (String) resultMap.get("keyspace");
263 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
264 resultMap.remove("keyspace");
265 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CURRENT_LOCK)) {
266 return response.status(Status.UNAUTHORIZED)
267 .entity(new JsonResponse(ResultType.FAILURE)
268 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
272 String who = MusicCore.whoseTurnIsIt(lockName);
273 ResultType status = ResultType.SUCCESS;
276 status = ResultType.FAILURE;
277 error = "There was a problem getting the lock holder";
278 logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
279 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
281 return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
283 EELFLoggerDelegate.mdcRemove("keyspace");
289 @ApiOperation(value = "Lock State",
290 notes = "Returns current Lock State and Holder.",
291 response = Map.class)
292 @Produces(MediaType.APPLICATION_JSON)
293 public Response currentLockState(
294 @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
295 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
296 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
297 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
298 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
299 @ApiParam(value = "Application namespace",
300 required = true) @HeaderParam("ns") String ns) throws Exception{
302 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
303 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
304 if (resultMap.containsKey("Error")) {
305 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
306 response.status(Status.BAD_REQUEST);
307 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
309 String keyspaceName = (String) resultMap.get("keyspace");
310 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
311 resultMap.remove("keyspace");
312 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CURRENT_LOCK)) {
313 return response.status(Status.UNAUTHORIZED)
314 .entity(new JsonResponse(ResultType.FAILURE)
315 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
319 String who = MusicCore.whoseTurnIsIt(lockName);
320 ResultType status = ResultType.SUCCESS;
323 status = ResultType.FAILURE;
324 error = "There was a problem getting the lock holder";
325 logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
326 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
328 return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
330 EELFLoggerDelegate.mdcRemove("keyspace");
333 //MusicLockState mls = MusicZKCore.getMusicLockState(lockName);
334 // Map<String,Object> returnMap = null;
335 // JsonResponse jsonResponse = new JsonResponse(ResultType.FAILURE).setLock(lockName);
337 // jsonResponse.setError("");
338 // jsonResponse.setMessage("No lock object created yet..");
339 // logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
340 // return response.status(Status.BAD_REQUEST).entity(jsonResponse.toMap()).build();
342 // jsonResponse.setStatus(ResultType.SUCCESS);
343 // jsonResponse.setLockStatus(mls.getLockStatus());
344 // jsonResponse.setLockHolder(mls.getLockHolder());
345 // return response.status(Status.OK).entity(jsonResponse.toMap()).build();
352 * deletes the process from the zk queue
358 @Path("/release/{lockreference}")
359 @ApiOperation(value = "Release Lock",
360 notes = "deletes the process from the zk queue",
361 response = Map.class)
362 @Produces(MediaType.APPLICATION_JSON)
363 public Response unLock(@PathParam("lockreference") String lockId,
364 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
365 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
366 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
367 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
368 @ApiParam(value = "Application namespace",
369 required = true) @HeaderParam("ns") String ns) throws Exception{
371 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
372 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
373 if (resultMap.containsKey("Error")) {
374 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
375 response.status(Status.BAD_REQUEST);
376 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
379 String keyspaceName = (String) resultMap.get("keyspace");
380 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
381 resultMap.remove("keyspace");
382 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DELETE_LOCK)) {
383 return response.status(Status.UNAUTHORIZED)
384 .entity(new JsonResponse(ResultType.FAILURE)
385 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
389 boolean voluntaryRelease = true;
390 MusicLockState mls = MusicCore.releaseLock(lockId,voluntaryRelease);
391 if(mls.getErrorMessage() != null) {
392 resultMap.put(ResultType.EXCEPTION.getResult(), mls.getErrorMessage());
393 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
394 return response.status(Status.BAD_REQUEST).entity(resultMap).build();
396 Map<String,Object> returnMap = null;
397 if (mls.getLockStatus() == MusicLockState.LockStatus.UNLOCKED) {
398 returnMap = new JsonResponse(ResultType.SUCCESS).setLock(lockId)
399 .setLockStatus(mls.getLockStatus()).toMap();
400 response.status(Status.OK);
402 if (mls.getLockStatus() == MusicLockState.LockStatus.LOCKED) {
403 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
404 returnMap = new JsonResponse(ResultType.FAILURE).setLock(lockId)
405 .setLockStatus(mls.getLockStatus()).toMap();
406 response.status(Status.BAD_REQUEST);
408 return response.entity(returnMap).build();
410 EELFLoggerDelegate.mdcRemove("keyspace");
420 @Path("/delete/{lockname}")
421 @ApiOperation(value = "Delete Lock", response = Map.class)
422 @Produces(MediaType.APPLICATION_JSON)
423 public Response deleteLock(@PathParam("lockname") String lockName,
424 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
425 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
426 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
427 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
428 @ApiParam(value = "Application namespace",
429 required = true) @HeaderParam("ns") String ns) throws Exception{
431 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
432 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
433 if (resultMap.containsKey("Error")) {
434 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
435 response.status(Status.BAD_REQUEST);
436 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
439 String keyspaceName = (String) resultMap.get("keyspace");
440 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
441 resultMap.remove("keyspace");
442 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DELETE_LOCK)) {
443 return response.status(Status.UNAUTHORIZED)
444 .entity(new JsonResponse(ResultType.FAILURE)
445 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
450 MusicCore.deleteLock(lockName);
451 }catch (Exception e) {
452 logger.error(EELFLoggerDelegate.errorLogger, e);
453 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
455 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).toMap()).build();
457 EELFLoggerDelegate.mdcRemove("keyspace");