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.exceptions.MusicLockingException;
51 import org.onap.music.lockingservice.cassandra.MusicLockState;
52 import org.onap.music.main.MusicCore;
53 import org.onap.music.main.MusicUtil;
54 import org.onap.music.main.ResultType;
55 import org.onap.music.main.ReturnType;
56 import org.onap.music.response.jsonobjects.JsonResponse;
58 import io.swagger.annotations.Api;
59 import io.swagger.annotations.ApiOperation;
60 import io.swagger.annotations.ApiParam;
64 @Api(value="Lock Api")
65 public class RestMusicLocksAPI {
67 private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicLocksAPI.class);
68 private static final String XMINORVERSION = "X-minorVersion";
69 private static final String XPATCHVERSION = "X-patchVersion";
70 private static final String VERSION = "v2";
72 private MusicAuthenticator authenticator = new MusicAAFAuthentication();
75 * Puts the requesting process in the q for this lock. The corresponding
76 * node will be created if it did not already exist
83 @Path("/create/{lockname}")
84 @ApiOperation(value = "Create Lock",
85 notes = "Puts the requesting process in the q for this lock." +
86 " The corresponding lock will be created if it did not already exist." +
87 " Lock Name is the \"key\" of the form keyspaceName.tableName.rowId",
89 @Produces(MediaType.APPLICATION_JSON)
90 public Response createLockReference(
91 @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
92 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
93 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
94 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
95 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
96 @ApiParam(value = "Application namespace",
97 required = true) @HeaderParam("ns") String ns) throws Exception{
99 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
100 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
101 if (resultMap.containsKey("Error")) {
102 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
103 response.status(Status.BAD_REQUEST);
104 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
106 String keyspaceName = (String) resultMap.get("keyspace");
107 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
109 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CREATE_LOCKREF)) {
110 return response.status(Status.UNAUTHORIZED)
111 .entity(new JsonResponse(ResultType.FAILURE)
112 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
116 ResultType status = ResultType.SUCCESS;
119 lockId= MusicCore.createLockReference(lockName);
120 } catch (MusicLockingException e) {
121 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
124 if (lockId == null) {
125 status = ResultType.FAILURE;
126 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
127 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError("Lock Id is null").toMap()).build();
129 return response.status(Status.OK).entity(new JsonResponse(status).setLock(lockId).toMap()).build();
131 EELFLoggerDelegate.mdcRemove("keyspace");
137 * Checks if the node is in the top of the queue and hence acquires the lock
144 @Path("/acquire/{lockreference}")
145 @ApiOperation(value = "Aquire Lock",
146 notes = "Checks if the node is in the top of the queue and hence acquires the lock",
147 response = Map.class)
148 @Produces(MediaType.APPLICATION_JSON)
149 public Response accquireLock(
150 @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId,
151 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
152 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
153 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
154 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
155 @ApiParam(value = "Application namespace",
156 required = true) @HeaderParam("ns") String ns) throws Exception{
158 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
159 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
160 if (resultMap.containsKey("Error")) {
161 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
162 response.status(Status.BAD_REQUEST);
163 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
166 String keyspaceName = (String) resultMap.get("keyspace");
167 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
169 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.ACQUIRE_LOCK)) {
170 return response.status(Status.UNAUTHORIZED)
171 .entity(new JsonResponse(ResultType.FAILURE)
172 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
177 String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
178 ReturnType lockStatus = MusicCore.acquireLock(lockName,lockId);
179 if ( lockStatus.getResult().equals(ResultType.SUCCESS)) {
180 response.status(Status.OK);
182 response.status(Status.BAD_REQUEST);
184 return response.entity(new JsonResponse(lockStatus.getResult()).setLock(lockId).setMessage(lockStatus.getMessage()).toMap()).build();
185 } catch (Exception e) {
186 logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId, ErrorSeverity.CRITICAL,
187 ErrorTypes.LOCKINGERROR, e);
188 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Unable to aquire lock").toMap()).build();
191 EELFLoggerDelegate.mdcRemove("keyspace");
199 @Path("/acquire-with-lease/{lockreference}")
200 @ApiOperation(value = "Aquire Lock with Lease", response = Map.class)
201 @Consumes(MediaType.APPLICATION_JSON)
202 @Produces(MediaType.APPLICATION_JSON)
203 public Response accquireLockWithLease(JsonLeasedLock lockObj,
204 @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId,
205 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
206 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
207 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
208 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
209 @ApiParam(value = "Application namespace",
210 required = true) @HeaderParam("ns") String ns) throws Exception{
212 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
213 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
214 if (resultMap.containsKey("Error")) {
215 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
216 response.status(Status.BAD_REQUEST);
217 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
219 String keyspaceName = (String) resultMap.get("keyspace");
220 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
221 resultMap.remove("keyspace");
222 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.ACQUIRE_LOCK)) {
223 return response.status(Status.UNAUTHORIZED)
224 .entity(new JsonResponse(ResultType.FAILURE)
225 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
229 String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
230 ReturnType lockLeaseStatus = MusicCore.acquireLockWithLease(lockName, lockId, lockObj.getLeasePeriod());
231 if ( lockLeaseStatus.getResult().equals(ResultType.SUCCESS)) {
232 response.status(Status.OK);
234 response.status(Status.BAD_REQUEST);
236 return response.entity(new JsonResponse(lockLeaseStatus.getResult()).setLock(lockName)
237 .setMessage(lockLeaseStatus.getMessage())
238 .setLockLease(String.valueOf(lockObj.getLeasePeriod())).toMap()).build();
240 EELFLoggerDelegate.mdcRemove("keyspace");
246 @Path("/enquire/{lockname}")
247 @ApiOperation(value = "Get Lock Holder",
248 notes = "Gets the current Lock Holder",
249 response = Map.class)
250 @Produces(MediaType.APPLICATION_JSON)
251 public Response currentLockHolder(
252 @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
253 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
254 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
255 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
256 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
257 @ApiParam(value = "Application namespace",
258 required = true) @HeaderParam("ns") String ns) throws Exception{
260 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
261 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
262 if (resultMap.containsKey("Error")) {
263 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
264 response.status(Status.BAD_REQUEST);
265 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
268 String keyspaceName = (String) resultMap.get("keyspace");
269 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
270 resultMap.remove("keyspace");
271 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CURRENT_LOCK)) {
272 return response.status(Status.UNAUTHORIZED)
273 .entity(new JsonResponse(ResultType.FAILURE)
274 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
278 String who = MusicCore.whoseTurnIsIt(lockName);
279 ResultType status = ResultType.SUCCESS;
282 status = ResultType.FAILURE;
283 error = "There was a problem getting the lock holder";
284 logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
285 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
287 return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
289 EELFLoggerDelegate.mdcRemove("keyspace");
295 @ApiOperation(value = "Lock State",
296 notes = "Returns current Lock State and Holder.",
297 response = Map.class)
298 @Produces(MediaType.APPLICATION_JSON)
299 public Response currentLockState(
300 @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
301 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
302 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
303 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
304 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
305 @ApiParam(value = "Application namespace",
306 required = true) @HeaderParam("ns") String ns) throws Exception{
308 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
309 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
310 if (resultMap.containsKey("Error")) {
311 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
312 response.status(Status.BAD_REQUEST);
313 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
315 String keyspaceName = (String) resultMap.get("keyspace");
316 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
317 resultMap.remove("keyspace");
318 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.CURRENT_LOCK)) {
319 return response.status(Status.UNAUTHORIZED)
320 .entity(new JsonResponse(ResultType.FAILURE)
321 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
325 String who = MusicCore.whoseTurnIsIt(lockName);
326 ResultType status = ResultType.SUCCESS;
329 status = ResultType.FAILURE;
330 error = "There was a problem getting the lock holder";
331 logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
332 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
334 return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
336 EELFLoggerDelegate.mdcRemove("keyspace");
343 * deletes the process from the lock queue
349 @Path("/release/{lockreference}")
350 @ApiOperation(value = "Release Lock",
351 notes = "deletes the process from the lock queue",
352 response = Map.class)
353 @Produces(MediaType.APPLICATION_JSON)
354 public Response unLock(@PathParam("lockreference") String lockId,
355 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
356 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
357 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
358 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
359 @ApiParam(value = "Application namespace",
360 required = true) @HeaderParam("ns") String ns) throws Exception{
362 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
363 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
364 if (resultMap.containsKey("Error")) {
365 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
366 response.status(Status.BAD_REQUEST);
367 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
370 String keyspaceName = (String) resultMap.get("keyspace");
371 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
372 resultMap.remove("keyspace");
373 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DELETE_LOCK)) {
374 return response.status(Status.UNAUTHORIZED)
375 .entity(new JsonResponse(ResultType.FAILURE)
376 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
380 boolean voluntaryRelease = true;
381 MusicLockState mls = MusicCore.releaseLock(lockId,voluntaryRelease);
382 if(mls.getErrorMessage() != null) {
383 resultMap.put(ResultType.EXCEPTION.getResult(), mls.getErrorMessage());
384 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
385 return response.status(Status.BAD_REQUEST).entity(resultMap).build();
387 Map<String,Object> returnMap = null;
388 if (mls.getLockStatus() == MusicLockState.LockStatus.UNLOCKED) {
389 returnMap = new JsonResponse(ResultType.SUCCESS).setLock(lockId)
390 .setLockStatus(mls.getLockStatus()).toMap();
391 response.status(Status.OK);
393 if (mls.getLockStatus() == MusicLockState.LockStatus.LOCKED) {
394 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
395 returnMap = new JsonResponse(ResultType.FAILURE).setLock(lockId)
396 .setLockStatus(mls.getLockStatus()).toMap();
397 response.status(Status.BAD_REQUEST);
399 return response.entity(returnMap).build();
401 EELFLoggerDelegate.mdcRemove("keyspace");
411 @Path("/delete/{lockname}")
412 @ApiOperation(value = "Delete Lock", response = Map.class, hidden = true, notes = "Deprecated")
413 @Produces(MediaType.APPLICATION_JSON)
415 public Response deleteLock(@PathParam("lockname") String lockName,
416 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
417 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
418 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
419 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
420 @ApiParam(value = "Application namespace",
421 required = true) @HeaderParam("ns") String ns) throws Exception{
423 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
424 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
425 if (resultMap.containsKey("Error")) {
426 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
427 response.status(Status.BAD_REQUEST);
428 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
431 String keyspaceName = (String) resultMap.get("keyspace");
432 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
433 resultMap.remove("keyspace");
434 if (!authenticator.authenticateUser(ns, authorization, keyspaceName, aid, Operation.DELETE_LOCK)) {
435 return response.status(Status.UNAUTHORIZED)
436 .entity(new JsonResponse(ResultType.FAILURE)
437 .setError("Unauthorized: Please check username, password and make sure your app is onboarded")
442 MusicCore.deleteLock(lockName);
443 }catch (Exception e) {
444 logger.error(EELFLoggerDelegate.errorLogger, e);
445 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
447 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).toMap()).build();
449 EELFLoggerDelegate.mdcRemove("keyspace");