Release initial Oslo CCSDK maven artifacts
[ccsdk/features.git] / lib / rlock / src / main / java / org / onap / ccsdk / features / lib / rlock / SynchronizedFunction.java
1 package org.onap.ccsdk.features.lib.rlock;
2
3 import java.security.SecureRandom;
4 import java.util.Collection;
5 import java.util.HashSet;
6 import java.util.Set;
7
8 /**
9  * <p>
10  * A simple abstract base class, providing functionality similar to the <tt>synchronized</tt> block
11  * in Java. Derived class provides the set of resources that need synchronized access and the
12  * processing method that is executed while the set of resources is locked (override <tt>_exec</tt>
13  * method). This class uses the {@link LockHelper} service to lock the resources, execute the
14  * processing method and then unlock the resources.
15  * </p>
16  * <p>
17  * Example:
18  * </p>
19  *
20  * <pre style="color:darkblue;">
21  * public class BandwidthCheckFunction extends SynchronizedFunction {
22  *
23  *     private PortBandwidthDao portBandwidthDao;
24  *     private int neededBandwidth;
25  *     private int bandwidthLimit;
26  *
27  *     private boolean successful; // Output
28  *
29  *     public BandwidthCheckFunction(LockHelper lockHelper, PortBandwidthDao portBandwidthDao, String portId,
30  *             int neededBandwidth, int bandwidthLimit) {
31  *         super(lockHelper, Collections.singleton(portId + "-Bandwidth"), 60); // 60 sec lockTimeout
32  *         this.portBandwidthDao = portBandwidthDao;
33  *         this.neededBandwidth = neededBandwidth;
34  *         this.bandwidthLimit = bandwidthLimit;
35  *     }
36  *
37  *     {@literal @}Override
38  *     protected void _exec() {
39  *         int usedBandwidth = portBandwidthDao.readUsedBandwidth("Port-123");
40  *         if (usedBandwidth + neededBandwidth <= bandwidthLimit) {
41  *             portBandwidthDao.updateUsedBandwidth("Port-123", usedBandwidth + neededBandwidth);
42  *             successful = true;
43  *         } else {
44  *             successful = false;
45  *         }
46  *     }
47  *
48  *     public boolean isSuccessful() {
49  *         return successful;
50  *     }
51  * }
52  *
53  * ..........
54  *
55  *     BandwidthCheckFunction func = new BandwidthCheckFunction(lockHelper, portBandwidthDao, "Port-123", 100, 1000);
56  *     func.exec();
57  *     boolean success = func.isSuccessful();
58  * ..........
59  * </pre>
60  *
61  * @see LockHelper
62  */
63 public abstract class SynchronizedFunction {
64
65     private Set<String> syncSet;
66     private String lockRequester;
67     private int lockTimeout; // Seconds
68     private LockHelper lockHelper;
69
70     /**
71      * @param lockHelper {@link LockHelper} service implementation
72      * @param syncSet the set of resources to be locked during processing
73      * @param lockTimeout the lock expiration timeout (see {@link LockHelper#lock(String, String, int)
74      *        LockHelper.lock})
75      */
76     protected SynchronizedFunction(LockHelper lockHelper, Collection<String> syncSet, int lockTimeout) {
77         this.lockHelper = lockHelper;
78         this.syncSet = new HashSet<>(syncSet);
79         lockRequester = generateLockRequester();
80         this.lockTimeout = lockTimeout;
81     }
82
83     /**
84      * Implement this method with the required processing. This method is executed while the resources
85      * are locked (<tt>syncSet</tt> provided in the constructor).
86      */
87     protected abstract void _exec();
88
89     /**
90      * Call this method to execute the provided processing in the derived class (the implemented
91      * <tt>_exec</tt> method).
92      */
93     public void exec() {
94         lockHelper.lock(syncSet, lockRequester, lockTimeout);
95         try {
96             _exec();
97         } finally {
98             lockHelper.unlock(syncSet, true);
99         }
100     }
101
102     private static String generateLockRequester() {
103         SecureRandom random = new SecureRandom();
104         return "SynchronizedFunction-" + (random.nextInt() % 1000000);
105     }
106 }