Fix license headers
[ccsdk/sli/adaptors.git] / resource-assignment / provider / src / main / java / org / openecomp / sdnc / lock / comp / LockHelperImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                      reserved.
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
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
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=========================================================
20  */
21
22 package org.openecomp.sdnc.lock.comp;
23
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
30 import org.openecomp.sdnc.lock.dao.ResourceLockDao;
31 import org.openecomp.sdnc.lock.data.ResourceLock;
32
33 public class LockHelperImpl implements LockHelper {
34
35     private ResourceLockDao resourceLockDao;
36     private int retryCount = 10;
37     private int lockWait = 5; // Seconds
38
39     @Override
40     public void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */) {
41         lock(Collections.singleton(resourceName), lockRequester, lockTimeout);
42     }
43
44     @Override
45     public void unlock(String resourceName, boolean force) {
46         unlock(Collections.singleton(resourceName), force);
47     }
48
49     @Override
50     public void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) {
51         for (int i = 0; true; i++) {
52             try {
53                 tryLock(resourceNameList, lockRequester, lockTimeout);
54                 return;
55             } catch (ResourceLockedException e) {
56                 if (i > retryCount)
57                     throw e;
58                 try {
59                     Thread.sleep(lockWait * 1000);
60                 } catch (InterruptedException ex) {
61                 }
62             }
63         }
64     }
65
66     @Override
67     public void unlock(Collection<String> lockNames, boolean force) {
68         if (lockNames == null || lockNames.size() == 0)
69             return;
70
71         resourceLockDao.lockTable();
72
73         try {
74             for (String name : lockNames) {
75                 ResourceLock l = resourceLockDao.getByResourceName(name);
76                 if (l != null)
77                     if (force || l.lockCount == 1)
78                         resourceLockDao.delete(l.id);
79                     else
80                         resourceLockDao.decrementLockCount(l.id);
81             }
82         } finally {
83             resourceLockDao.unlockTable();
84         }
85     }
86
87     public void tryLock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) {
88         if (resourceNameList == null || resourceNameList.size() == 0)
89             return;
90
91         lockRequester = generateLockRequester(lockRequester, 100);
92
93         resourceLockDao.lockTable();
94
95         try {
96             // First check if all requested records are available to lock
97
98             Date now = new Date();
99
100             List<ResourceLock> dbLockList = new ArrayList<ResourceLock>();
101             List<String> insertLockNameList = new ArrayList<String>();
102             for (String name : resourceNameList) {
103                 ResourceLock l = resourceLockDao.getByResourceName(name);
104
105                 boolean canLock =
106                         l == null || now.getTime() > l.expirationTime.getTime() || lockRequester != null &&
107                                 lockRequester.equals(l.lockHolder) || l.lockCount <= 0;
108                 if (!canLock)
109                     throw new ResourceLockedException(l.resourceName, l.lockHolder, lockRequester);
110
111                 if (l != null)
112                     dbLockList.add(l);
113                 else
114                     insertLockNameList.add(name);
115             }
116
117             // Update the lock info in DB
118             for (ResourceLock l : dbLockList)
119                 resourceLockDao.update(l.id, now, new Date(now.getTime() + lockTimeout * 1000), l.lockCount + 1);
120
121             // Insert records for those that are not yet there
122             for (String lockName : insertLockNameList) {
123                 ResourceLock l = new ResourceLock();
124                 l.resourceName = lockName;
125                 l.lockHolder = lockRequester;
126                 l.lockTime = now;
127                 l.expirationTime = new Date(now.getTime() + lockTimeout * 1000);
128                 l.lockCount = 1;
129                 resourceLockDao.add(l);
130             }
131         } finally {
132             resourceLockDao.unlockTable();
133         }
134     }
135
136     private static String generateLockRequester(String name, int maxLength) {
137         if (name == null)
138             name = "";
139         int l1 = name.length();
140         String tname = Thread.currentThread().getName();
141         int l2 = tname.length();
142         if (l1 + l2 + 1 > maxLength) {
143             int maxl1 = maxLength / 2;
144             if (l1 > maxl1) {
145                 name = name.substring(0, maxl1);
146                 l1 = maxl1;
147             }
148             int maxl2 = maxLength - l1 - 1;
149             if (l2 > maxl2)
150                 tname = tname.substring(0, 6) + "..." + tname.substring(l2 - maxl2 + 9);
151         }
152         return tname + '-' + name;
153     }
154
155     public void setResourceLockDao(ResourceLockDao resourceLockDao) {
156         this.resourceLockDao = resourceLockDao;
157     }
158
159     public void setRetryCount(int retryCount) {
160         this.retryCount = retryCount;
161     }
162
163     public void setLockWait(int lockWait /* Seconds */) {
164         this.lockWait = lockWait;
165     }
166 }