2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (c) 2017 AT&T Intellectual Property
6 * ===================================================================
7 * * Modifications Copyright (c) 2019 Samsung
8 * ===================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
22 * ============LICENSE_END=============================================
23 * ====================================================================
26 package org.onap.music.rest;
28 import java.util.List;
31 import javax.ws.rs.Consumes;
32 import javax.ws.rs.DELETE;
33 import javax.ws.rs.GET;
34 import javax.ws.rs.HeaderParam;
35 import javax.ws.rs.POST;
36 import javax.ws.rs.Path;
37 import javax.ws.rs.PathParam;
38 import javax.ws.rs.Produces;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.Response;
41 import javax.ws.rs.core.Response.ResponseBuilder;
42 import javax.ws.rs.core.Response.Status;
44 import org.onap.music.datastore.jsonobjects.JsonLeasedLock;
45 import org.onap.music.datastore.jsonobjects.JsonLock;
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.LockType;
52 import org.onap.music.lockingservice.cassandra.MusicLockState;
53 import org.onap.music.main.MusicCore;
54 import org.onap.music.main.MusicUtil;
55 import org.onap.music.main.ResultType;
56 import org.onap.music.main.ReturnType;
57 import org.onap.music.response.jsonobjects.JsonResponse;
59 import io.swagger.annotations.Api;
60 import io.swagger.annotations.ApiOperation;
61 import io.swagger.annotations.ApiParam;
65 @Api(value="Lock Api")
66 public class RestMusicLocksAPI {
68 private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicLocksAPI.class);
69 private static final String XMINORVERSION = "X-minorVersion";
70 private static final String XPATCHVERSION = "X-patchVersion";
71 private static final String VERSION = "v2";
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 @Consumes(MediaType.APPLICATION_JSON)
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,
97 @ApiParam(value = "Application namespace",
98 required = true) @HeaderParam("ns") String ns) throws Exception{
100 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
101 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
102 if (resultMap.containsKey("Error")) {
103 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
104 response.status(Status.BAD_REQUEST);
105 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
107 String keyspaceName = (String) resultMap.get("keyspace");
108 EELFLoggerDelegate.mdcPut("keyspace", "( " + keyspaceName + " ) ");
110 //default lock type is write, as this is always semantically safe
111 LockType locktype = LockType.WRITE;
112 if (lockObject!=null && lockObject.getLocktype()!=null) {
113 locktype = lockObject.getLocktype();
117 lockId= MusicCore.createLockReference(lockName, locktype);
118 } catch (MusicLockingException e) {
119 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
122 if (lockId == null) {
123 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
124 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Lock Id is null").toMap()).build();
126 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setLock(lockId).toMap()).build();
128 EELFLoggerDelegate.mdcRemove("keyspace");
134 * Checks if the node is in the top of the queue and hence acquires the lock
141 @Path("/acquire/{lockreference}")
142 @ApiOperation(value = "Aquire Lock",
143 notes = "Checks if the node is in the top of the queue and hence acquires the lock",
144 response = Map.class)
145 @Produces(MediaType.APPLICATION_JSON)
146 public Response accquireLock(
147 @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId,
148 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
149 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
150 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
151 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
152 @ApiParam(value = "Application namespace",
153 required = true) @HeaderParam("ns") String ns) throws Exception{
155 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
156 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
157 if (resultMap.containsKey("Error")) {
158 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
159 response.status(Status.BAD_REQUEST);
160 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
163 String keyspaceName = (String) resultMap.get("keyspace");
164 EELFLoggerDelegate.mdcPut("keyspace", "( " + keyspaceName + " ) ");
166 String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
167 ReturnType lockStatus = MusicCore.acquireLock(lockName,lockId);
168 if ( lockStatus.getResult().equals(ResultType.SUCCESS)) {
169 response.status(Status.OK);
171 response.status(Status.BAD_REQUEST);
173 return response.entity(new JsonResponse(lockStatus.getResult()).setLock(lockId).setMessage(lockStatus.getMessage()).toMap()).build();
174 } catch (Exception e) {
175 logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId, ErrorSeverity.CRITICAL,
176 ErrorTypes.LOCKINGERROR, e);
177 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Unable to aquire lock").toMap()).build();
180 EELFLoggerDelegate.mdcRemove("keyspace");
188 @Path("/acquire-with-lease/{lockreference}")
189 @ApiOperation(value = "Aquire Lock with Lease", response = Map.class)
190 @Consumes(MediaType.APPLICATION_JSON)
191 @Produces(MediaType.APPLICATION_JSON)
192 public Response accquireLockWithLease(JsonLeasedLock lockObj,
193 @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId,
194 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
195 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
196 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
197 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
198 @ApiParam(value = "Application namespace",
199 required = true) @HeaderParam("ns") String ns) throws Exception{
201 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
202 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
203 if (resultMap.containsKey("Error")) {
204 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
205 response.status(Status.BAD_REQUEST);
206 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
208 String keyspaceName = (String) resultMap.get("keyspace");
209 EELFLoggerDelegate.mdcPut("keyspace", "( " + keyspaceName + " ) ");
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);
215 response.status(Status.BAD_REQUEST);
217 return response.entity(new JsonResponse(lockLeaseStatus.getResult()).setLock(lockName)
218 .setMessage(lockLeaseStatus.getMessage())
219 .setLockLease(String.valueOf(lockObj.getLeasePeriod())).toMap()).build();
221 EELFLoggerDelegate.mdcRemove("keyspace");
227 @Path("/enquire/{lockname}")
228 @ApiOperation(value = "Get the top of the lock queue",
229 notes = "Gets the current single lockholder at top of lock queue",
230 response = Map.class)
231 @Produces(MediaType.APPLICATION_JSON)
232 public Response enquireLock(
233 @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
234 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
235 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
236 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
237 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
238 @ApiParam(value = "Application namespace",
239 required = true) @HeaderParam("ns") String ns) throws Exception{
241 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
242 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
243 if (resultMap.containsKey("Error")) {
244 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
245 response.status(Status.BAD_REQUEST);
246 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
248 String keyspaceName = (String) resultMap.get("keyspace");
249 EELFLoggerDelegate.mdcPut("keyspace", "( " + keyspaceName + " ) ");
250 String who = MusicCore.whoseTurnIsIt(lockName);
251 ResultType status = ResultType.SUCCESS;
254 status = ResultType.FAILURE;
255 error = "There was a problem getting the lock holder";
256 logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
257 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
259 return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
261 EELFLoggerDelegate.mdcRemove("keyspace");
266 @Path("/getCurrentLockHolders/{lockname}")
267 @ApiOperation(value = "Get Lock Holders",
268 notes = "Gets the current Lock Holders",
269 response = Map.class)
270 @Produces(MediaType.APPLICATION_JSON)
271 public Response currentLockHolder(@ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
272 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
273 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
274 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
275 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
276 @ApiParam(value = "Application namespace",
277 required = true) @HeaderParam("ns") String ns) throws Exception{
279 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
280 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
281 if (resultMap.containsKey("Error")) {
282 logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA, ErrorSeverity.CRITICAL,
283 ErrorTypes.GENERALSERVICEERROR);
284 response.status(Status.BAD_REQUEST);
285 return response.entity(
286 new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap())
289 String keyspaceName = (String) resultMap.get("keyspace");
290 List<String> who = MusicCore.getCurrentLockHolders(lockName);
291 ResultType status = ResultType.SUCCESS;
294 status = ResultType.FAILURE;
295 error = "There was a problem getting the lock holder";
296 logger.error(EELFLoggerDelegate.errorLogger, "There was a problem getting the lock holder",
297 AppMessages.INCORRECTDATA, ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
298 return response.status(Status.BAD_REQUEST)
299 .entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap())
302 return response.status(Status.OK)
303 .entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap())
306 EELFLoggerDelegate.mdcRemove("keyspace");
313 @ApiOperation(value = "Lock State",
314 notes = "Returns current Lock State and Holder.",
315 response = Map.class)
316 @Produces(MediaType.APPLICATION_JSON)
317 public Response currentLockState(
318 @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName,
319 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
320 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
321 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
322 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
323 @ApiParam(value = "Application namespace",
324 required = true) @HeaderParam("ns") String ns) throws Exception{
326 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
327 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
328 if (resultMap.containsKey("Error")) {
329 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
330 response.status(Status.BAD_REQUEST);
331 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
333 String keyspaceName = (String) resultMap.get("keyspace");
334 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
335 String who = MusicCore.whoseTurnIsIt(lockName);
336 ResultType status = ResultType.SUCCESS;
339 status = ResultType.FAILURE;
340 error = "There was a problem getting the lock holder";
341 logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
342 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
344 return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
346 EELFLoggerDelegate.mdcRemove("keyspace");
353 * deletes the process from the lock queue
359 @Path("/release/{lockreference}")
360 @ApiOperation(value = "Release Lock",
361 notes = "deletes the process from the lock queue",
362 response = Map.class)
363 @Produces(MediaType.APPLICATION_JSON)
364 public Response unLock(@PathParam("lockreference") String lockId,
365 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
366 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
367 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
368 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
369 @ApiParam(value = "Application namespace",
370 required = true) @HeaderParam("ns") String ns) throws Exception{
372 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
373 Map<String, Object> resultMap = MusicCore.validateLock(lockId);
374 if (resultMap.containsKey("Error")) {
375 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
376 response.status(Status.BAD_REQUEST);
377 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
380 String keyspaceName = (String) resultMap.get("keyspace");
381 EELFLoggerDelegate.mdcPut("keyspace", "( "+keyspaceName+" ) ");
382 boolean voluntaryRelease = true;
383 MusicLockState mls = MusicCore.releaseLock(lockId,voluntaryRelease);
384 if(mls.getErrorMessage() != null) {
385 resultMap.put(ResultType.EXCEPTION.getResult(), mls.getErrorMessage());
386 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
387 return response.status(Status.BAD_REQUEST).entity(resultMap).build();
389 Map<String,Object> returnMap = null;
390 if (mls.getLockStatus() == MusicLockState.LockStatus.UNLOCKED) {
391 returnMap = new JsonResponse(ResultType.SUCCESS).setLock(lockId)
392 .setLockStatus(mls.getLockStatus()).toMap();
393 response.status(Status.OK);
395 if (mls.getLockStatus() == MusicLockState.LockStatus.LOCKED) {
396 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
397 returnMap = new JsonResponse(ResultType.FAILURE).setLock(lockId)
398 .setLockStatus(mls.getLockStatus()).toMap();
399 response.status(Status.BAD_REQUEST);
401 return response.entity(returnMap).build();
403 EELFLoggerDelegate.mdcRemove("keyspace");
413 @Path("/delete/{lockname}")
414 @ApiOperation(value = "Delete Lock", response = Map.class)
415 @Produces(MediaType.APPLICATION_JSON)
416 public Response deleteLock(@PathParam("lockname") String lockName,
417 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
418 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
419 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
420 @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization,
421 @ApiParam(value = "Application namespace",
422 required = true) @HeaderParam("ns") String ns) throws Exception{
424 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
425 Map<String, Object> resultMap = MusicCore.validateLock(lockName);
426 if (resultMap.containsKey("Error")) {
427 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
428 response.status(Status.BAD_REQUEST);
429 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(resultMap.get("Error"))).toMap()).build();
432 String keyspaceName = (String) resultMap.get("keyspace");
433 EELFLoggerDelegate.mdcPut("keyspace", "( " + keyspaceName + " ) ");
435 MusicCore.destroyLockRef(lockName);
436 }catch (Exception e) {
437 logger.error(EELFLoggerDelegate.errorLogger, e);
438 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
440 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).toMap()).build();
442 EELFLoggerDelegate.mdcRemove("keyspace");