2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.sli.adaptors.lock.comp;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Date;
28 import java.util.List;
29 import org.onap.ccsdk.sli.adaptors.lock.dao.ResourceLockDao;
30 import org.onap.ccsdk.sli.adaptors.lock.data.ResourceLock;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 public class LockHelperImpl implements LockHelper {
36 private static final Logger log = LoggerFactory.getLogger(LockHelperImpl.class);
38 private ResourceLockDao resourceLockDao;
39 private int retryCount = 10;
40 private int lockWait = 5; // Seconds
43 public void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */) {
44 lock(resourceName, lockRequester, lockTimeout, lockWait, retryCount);
48 public void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */,
49 int lockWait /* Seconds */, int retryCount) {
50 lock(Collections.singleton(resourceName), lockRequester, lockTimeout, lockWait, retryCount);
54 public void unlock(String resourceName, boolean force) {
55 unlock(Collections.singleton(resourceName), force);
59 public void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) {
60 lock(resourceNameList, lockRequester, lockTimeout, lockWait, retryCount);
64 public void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */,
65 int lockWait /* Seconds */, int retryCount) {
66 for (int i = 0; true; i++) {
68 tryLock(resourceNameList, lockRequester, lockTimeout);
69 log.info("Resources locked: " + resourceNameList);
71 } catch (ResourceLockedException e) {
72 if (i >= retryCount) {
76 Thread.sleep(lockWait * 1000);
77 } catch (InterruptedException ex) {
78 log.error("Interrupted Exception", ex);
85 public void unlock(Collection<String> lockNames, boolean force) {
86 if (lockNames == null || lockNames.isEmpty()) {
91 for (String name : lockNames) {
92 ResourceLock l = resourceLockDao.getByResourceName(name);
94 if (force || l.lockCount == 1) {
95 resourceLockDao.delete(l.id);
97 resourceLockDao.decrementLockCount(l.id);
102 resourceLockDao.commit();
104 log.info("Resources unlocked: " + lockNames);
106 resourceLockDao.rollback();
110 public void tryLock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) {
111 if (resourceNameList == null || resourceNameList.isEmpty()) {
115 lockRequester = generateLockRequester(lockRequester, 100);
117 // First check if all requested records are available to lock
119 Date now = new Date();
122 List<ResourceLock> dbLockList = new ArrayList<>();
123 List<String> insertLockNameList = new ArrayList<>();
124 for (String name : resourceNameList) {
125 ResourceLock l = resourceLockDao.getByResourceName(name);
127 boolean canLock = l == null || now.getTime() > l.expirationTime.getTime() ||
128 lockRequester != null && lockRequester.equals(l.lockHolder) || l.lockCount <= 0;
130 throw new ResourceLockedException(l.resourceName, l.lockHolder, lockRequester);
134 if (now.getTime() > l.expirationTime.getTime() || l.lockCount <= 0) {
139 insertLockNameList.add(name);
143 // Update the lock info in DB
144 for (ResourceLock l : dbLockList) {
145 resourceLockDao.update(l.id, lockRequester, now, new Date(now.getTime() + lockTimeout * 1000), l.lockCount + 1);
148 // Insert records for those that are not yet there
149 for (String lockName : insertLockNameList) {
150 ResourceLock l = new ResourceLock();
151 l.resourceName = lockName;
152 l.lockHolder = lockRequester;
154 l.expirationTime = new Date(now.getTime() + lockTimeout * 1000);
158 resourceLockDao.add(l);
159 } catch (Exception e) {
160 log.info("Failed to insert lock record: " + lockName);
161 throw new ResourceLockedException(l.resourceName, "unknown", lockRequester);
165 resourceLockDao.commit();
170 resourceLockDao.rollback();
174 private static String generateLockRequester(String name, int maxLength) {
178 int l1 = name.length();
179 String tname = Thread.currentThread().getName();
180 int l2 = tname.length();
181 if (l1 + l2 + 1 > maxLength) {
182 int maxl1 = maxLength / 2;
184 name = name.substring(0, maxl1);
187 int maxl2 = maxLength - l1 - 1;
189 tname = tname.substring(0, 6) + "..." + tname.substring(l2 - maxl2 + 9);
192 return tname + '-' + name;
195 public void setResourceLockDao(ResourceLockDao resourceLockDao) {
196 this.resourceLockDao = resourceLockDao;
199 public void setRetryCount(int retryCount) {
200 this.retryCount = retryCount;
203 public void setLockWait(int lockWait /* Seconds */) {
204 this.lockWait = lockWait;