aboutsummaryrefslogtreecommitdiffstats
path: root/policy-core/src/main/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPI.java
blob: 9f42936d5b231139ab29865efe81660ab2df24ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 * ============LICENSE_START=======================================================
 * api-resource-locks
 * ================================================================================
 * Copyright (C) 2018 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.onap.policy.drools.core.lock;

import java.util.concurrent.Future;
import org.onap.policy.drools.utils.OrderedService;
import org.onap.policy.drools.utils.OrderedServiceImpl;

/**
 * Resource locks. Each lock has an "owner", which is intended to be unique across a
 * single instance of a running PolicyEngine.
 * <p>
 * This interface provides a way to invoke optional features at various points in the
 * code. At appropriate points in the application, the code iterates through this list,
 * invoking these optional methods.
 * <p>
 * Implementers may choose to implement a level of locking appropriate to the application.
 * For instance, they may choose to implement an engine-wide locking scheme, or they may
 * choose to implement a global locking scheme (e.g., through a shared DB).
 */
public interface PolicyResourceLockFeatureAPI extends OrderedService {

    /**
     * 'FeatureAPI.impl.getList()' returns an ordered list of objects implementing the
     * 'FeatureAPI' interface.
     */
    public static OrderedServiceImpl<PolicyResourceLockFeatureAPI> impl =
                    new OrderedServiceImpl<>(PolicyResourceLockFeatureAPI.class);

    /**
     * Callback that an implementer invokes, asynchronously, when a lock is acquired (or
     * denied). The implementer invokes the method to indicate that the lock was acquired
     * (or denied).
     */
    @FunctionalInterface
    public static interface Callback {

        /**
         * 
         * @param locked {@code true} if the lock was acquired, {@code false} if the lock
         *        was denied
         */
        public void set(boolean locked);
    }

    /**
     * Result of a requested operation.
     */
    public static enum OperResult {

        /**
         * The implementer accepted the request; no additional locking logic should be
         * performed.
         */
        OPER_ACCEPTED,

        /**
         * The implementer denied the request; no additional locking logic should be
         * performed.
         */
        OPER_DENIED,


        /**
         * The implementer did not handle the request; additional locking logic <i>should
         * be<i> performed.
         */
        OPER_UNHANDLED
    }

    /**
     * This method is called before a lock is acquired on a resource. If a callback is
     * provided, and the implementer is unable to acquire the lock immediately, then the
     * implementer will invoke the callback once the lock is acquired. If the implementer
     * handled the request, then it will return a future, which may be in one of three
     * states:
     * <dl>
     * <dt>isDone()=true and get()=true</dt>
     * <dd>the lock has been acquired; the callback may or may not have been invoked</dd>
     * <dt>isDone()=true and get()=false</dt>
     * <dd>the lock request has been denied; the callback may or may not have been
     * invoked</dd>
     * <dt>isDone()=false</dt>
     * <dd>the lock was not immediately available and a callback was provided. The
     * callback will be invoked once the lock is acquired (or denied). In this case, the
     * future may be used to cancel the request</dd>
     * </dl>
     * 
     * @param resourceId
     * @param owner
     * @param callback function to invoke, if the requester wishes to wait for the lock to
     *        come available, {@code null} to provide immediate replies
     * @return a future for the lock, if the implementer handled the request, {@code null}
     *         if additional locking logic should be performed
     * @throws IllegalStateException if the owner already holds the lock or is already in
     *         the queue to get the lock
     */
    public default Future<Boolean> beforeLock(String resourceId, String owner, Callback callback) {
        return null;
    }

    /**
     * This method is called after a lock for a resource has been acquired or denied. This
     * may be invoked immediately, if the status can be determined immediately, or it may
     * be invoked asynchronously, once the status has been determined.
     * 
     * @param resourceId
     * @param owner
     * @param locked {@code true} if the lock was acquired, {@code false} if it was denied
     * @return {@code true} if the implementer handled the request, {@code false}
     *         otherwise
     */
    public default boolean afterLock(String resourceId, String owner, boolean locked) {
        return false;
    }

    /**
     * This method is called before a lock on a resource is released.
     * 
     * @param resourceId
     * @param owner
     * @return the result, where <b>OPER_DENIED</b> indicates that the lock is not
     *         currently held by the given owner
     */
    public default OperResult beforeUnlock(String resourceId, String owner) {
        return OperResult.OPER_UNHANDLED;
    }

    /**
     * This method is called after a lock on a resource is released.
     * 
     * @param resourceId
     * @param owner
     * @param unlocked {@code true} if the lock was released, {@code false} if the owner
     *        did not have a lock on the resource
     * @return {@code true} if the implementer handled the request, {@code false}
     *         otherwise
     */
    public default boolean afterUnlock(String resourceId, String owner, boolean unlocked) {
        return false;
    }

    /**
     * This method is called before a check is made to determine if a resource is locked.
     * 
     * @param resourceId
     * @return the result, where <b>OPER_ACCEPTED</b> indicates that the resource is
     *         locked, while <b>OPER_DENIED</b> indicates that it is not
     */
    public default OperResult beforeIsLocked(String resourceId) {
        return OperResult.OPER_UNHANDLED;
    }

    /**
     * This method is called before a check is made to determine if a particular owner
     * holds the lock on a resource.
     * 
     * @param resourceId
     * @param owner
     * @return the result, where <b>OPER_ACCEPTED</b> indicates that the resource is
     *         locked by the given owner, while <b>OPER_DENIED</b> indicates that it is
     *         not
     */
    public default OperResult beforeIsLockedBy(String resourceId, String owner) {
        return OperResult.OPER_UNHANDLED;
    }
}