From 09b58e1832480e9529124ae422f040028546daff Mon Sep 17 00:00:00 2001 From: Dan Timoney Date: Wed, 15 Feb 2017 14:59:20 -0500 Subject: Initial commit for OpenECOMP SDN-C adaptors Change-Id: I8d42e44d15fd85aee5b00d27e45da6751dda02b9 Signed-off-by: Dan Timoney --- .../org/openecomp/sdnc/lock/comp/LockHelper.java | 35 +++++ .../openecomp/sdnc/lock/comp/LockHelperImpl.java | 166 +++++++++++++++++++++ .../sdnc/lock/comp/ResourceLockedException.java | 41 +++++ .../sdnc/lock/comp/SynchronizedFunction.java | 56 +++++++ 4 files changed, 298 insertions(+) create mode 100644 resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/LockHelper.java create mode 100644 resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/LockHelperImpl.java create mode 100644 resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/ResourceLockedException.java create mode 100644 resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/SynchronizedFunction.java (limited to 'resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp') diff --git a/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/LockHelper.java b/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/LockHelper.java new file mode 100644 index 0000000..c7b5466 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/LockHelper.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdnc.lock.comp; + +import java.util.Collection; + +public interface LockHelper { + + void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */); + + void unlock(String resourceName, boolean force); + + void lock(Collection resourceNameList, String lockRequester, int lockTimeout /* Seconds */); + + void unlock(Collection resourceNameList, boolean force); +} diff --git a/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/LockHelperImpl.java b/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/LockHelperImpl.java new file mode 100644 index 0000000..139abfe --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/LockHelperImpl.java @@ -0,0 +1,166 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdnc.lock.comp; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import org.openecomp.sdnc.lock.dao.ResourceLockDao; +import org.openecomp.sdnc.lock.data.ResourceLock; + +public class LockHelperImpl implements LockHelper { + + private ResourceLockDao resourceLockDao; + private int retryCount = 10; + private int lockWait = 5; // Seconds + + @Override + public void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */) { + lock(Collections.singleton(resourceName), lockRequester, lockTimeout); + } + + @Override + public void unlock(String resourceName, boolean force) { + unlock(Collections.singleton(resourceName), force); + } + + @Override + public void lock(Collection resourceNameList, String lockRequester, int lockTimeout /* Seconds */) { + for (int i = 0; true; i++) { + try { + tryLock(resourceNameList, lockRequester, lockTimeout); + return; + } catch (ResourceLockedException e) { + if (i > retryCount) + throw e; + try { + Thread.sleep(lockWait * 1000); + } catch (InterruptedException ex) { + } + } + } + } + + @Override + public void unlock(Collection lockNames, boolean force) { + if (lockNames == null || lockNames.size() == 0) + return; + + resourceLockDao.lockTable(); + + try { + for (String name : lockNames) { + ResourceLock l = resourceLockDao.getByResourceName(name); + if (l != null) + if (force || l.lockCount == 1) + resourceLockDao.delete(l.id); + else + resourceLockDao.decrementLockCount(l.id); + } + } finally { + resourceLockDao.unlockTable(); + } + } + + public void tryLock(Collection resourceNameList, String lockRequester, int lockTimeout /* Seconds */) { + if (resourceNameList == null || resourceNameList.size() == 0) + return; + + lockRequester = generateLockRequester(lockRequester, 100); + + resourceLockDao.lockTable(); + + try { + // First check if all requested records are available to lock + + Date now = new Date(); + + List dbLockList = new ArrayList(); + List insertLockNameList = new ArrayList(); + for (String name : resourceNameList) { + ResourceLock l = resourceLockDao.getByResourceName(name); + + boolean canLock = + l == null || now.getTime() > l.expirationTime.getTime() || lockRequester != null && + lockRequester.equals(l.lockHolder) || l.lockCount <= 0; + if (!canLock) + throw new ResourceLockedException(l.resourceName, l.lockHolder, lockRequester); + + if (l != null) + dbLockList.add(l); + else + insertLockNameList.add(name); + } + + // Update the lock info in DB + for (ResourceLock l : dbLockList) + resourceLockDao.update(l.id, now, new Date(now.getTime() + lockTimeout * 1000), l.lockCount + 1); + + // Insert records for those that are not yet there + for (String lockName : insertLockNameList) { + ResourceLock l = new ResourceLock(); + l.resourceName = lockName; + l.lockHolder = lockRequester; + l.lockTime = now; + l.expirationTime = new Date(now.getTime() + lockTimeout * 1000); + l.lockCount = 1; + resourceLockDao.add(l); + } + } finally { + resourceLockDao.unlockTable(); + } + } + + private static String generateLockRequester(String name, int maxLength) { + if (name == null) + name = ""; + int l1 = name.length(); + String tname = Thread.currentThread().getName(); + int l2 = tname.length(); + if (l1 + l2 + 1 > maxLength) { + int maxl1 = maxLength / 2; + if (l1 > maxl1) { + name = name.substring(0, maxl1); + l1 = maxl1; + } + int maxl2 = maxLength - l1 - 1; + if (l2 > maxl2) + tname = tname.substring(0, 6) + "..." + tname.substring(l2 - maxl2 + 9); + } + return tname + '-' + name; + } + + public void setResourceLockDao(ResourceLockDao resourceLockDao) { + this.resourceLockDao = resourceLockDao; + } + + public void setRetryCount(int retryCount) { + this.retryCount = retryCount; + } + + public void setLockWait(int lockWait /* Seconds */) { + this.lockWait = lockWait; + } +} diff --git a/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/ResourceLockedException.java b/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/ResourceLockedException.java new file mode 100644 index 0000000..b2fa942 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/ResourceLockedException.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdnc.lock.comp; + +public class ResourceLockedException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private String lockName, lockHolder, lockRequester; + + public ResourceLockedException(String lockName, String lockHolder, String lockRequester) { + this.lockName = lockName; + this.lockHolder = lockHolder; + this.lockRequester = lockRequester; + } + + @Override + public String getMessage() { + return "Failed to lock [" + lockName + "] for [" + lockRequester + "]. Currently locked by [" + lockHolder + + "]."; + } +} diff --git a/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/SynchronizedFunction.java b/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/SynchronizedFunction.java new file mode 100644 index 0000000..0bbb053 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/openecomp/sdnc/lock/comp/SynchronizedFunction.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdnc.lock.comp; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public abstract class SynchronizedFunction { + + private Set synchset; + private String lockRequester; + private int lockTimeout; // Seconds + private LockHelper lockHelper; + + protected SynchronizedFunction(LockHelper lockHelper, Collection synchset, int lockTimeout) { + this.lockHelper = lockHelper; + this.synchset = new HashSet(synchset); + this.lockRequester = generateLockRequester(); + this.lockTimeout = lockTimeout; + } + + protected abstract void _exec(); + + public void exec() { + lockHelper.lock(synchset, lockRequester, lockTimeout); + try { + _exec(); + } finally { + lockHelper.unlock(synchset, true); + } + } + + private static String generateLockRequester() { + return "SynchronizedFunction-" + (int) (Math.random() * 1000000); + } +} -- cgit 1.2.3-korg