2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (c) 2017 AT&T Intellectual Property
6 * ===================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * ============LICENSE_END=============================================
20 * ====================================================================
22 package org.onap.music.lockingservice;
24 import org.apache.zookeeper.CreateMode;
25 import org.apache.zookeeper.KeeperException;
26 import org.apache.zookeeper.ZooDefs;
27 import org.apache.zookeeper.ZooKeeper;
28 import org.apache.zookeeper.data.ACL;
29 import org.apache.zookeeper.data.Stat;
30 import org.onap.music.eelf.logging.EELFLoggerDelegate;
31 import org.onap.music.lockingservice.ZooKeeperOperation;
32 import java.util.List;
33 import java.util.concurrent.atomic.AtomicBoolean;
36 * A base class for protocol implementations which provides a number of higher level helper methods
37 * for working with ZooKeeper along with retrying synchronous operations if the connection to
38 * ZooKeeper closes such as {@link #retryOperation(ZooKeeperOperation)}
41 class ProtocolSupport {
42 private EELFLoggerDelegate LOG = EELFLoggerDelegate.getLogger(ProtocolSupport.class);
44 protected ZooKeeper zookeeper;
45 private AtomicBoolean closed = new AtomicBoolean(false);
46 private long retryDelay = 500L;
47 private int retryCount = 10;
48 private List<ACL> acl = ZooDefs.Ids.OPEN_ACL_UNSAFE;
51 * Closes this strategy and releases any ZooKeeper resources; but keeps the ZooKeeper instance
55 if (closed.compareAndSet(false, true)) {
61 * return zookeeper client instance
63 * @return zookeeper client instance
65 public ZooKeeper getZookeeper() {
70 * return the acl its using
74 public List<ACL> getAcl() {
81 * @param acl the acl to set to
83 public void setAcl(List<ACL> acl) {
88 * get the retry delay in milliseconds
90 * @return the retry delay
92 public long getRetryDelay() {
97 * Sets the time waited between retry delays
99 * @param retryDelay the retry delay
101 public void setRetryDelay(long retryDelay) {
102 this.retryDelay = retryDelay;
106 * Allow derived classes to perform some custom closing operations to release resources
108 protected void doClose() {
109 throw new UnsupportedOperationException();
114 * Perform the given operation, retrying if the connection fails
116 * @return object. it needs to be cast to the callee's expected return type.
117 * @param operation FILL IN
118 * @throws KeeperException FILL IN
119 * @throws InterruptedException FILL IN
121 protected Object retryOperation(ZooKeeperOperation operation)
122 throws KeeperException, InterruptedException {
123 KeeperException exception = null;
124 for (int i = 0; i < retryCount; i++) {
126 return operation.execute();
127 } catch (KeeperException.SessionExpiredException e) {
128 LOG.debug("Session expired for: " + zookeeper + " so reconnecting due to: " + e, e);
130 } catch (KeeperException.ConnectionLossException e) {
131 if (exception == null) {
134 LOG.debug("Attempt " + i + " failed with connection loss so "
135 + "attempting to reconnect: " + e, e);
143 * Ensures that the given path exists with no data, the current ACL and no flags
145 * @param path the lock path
147 protected void ensurePathExists(String path) {
148 ensureExists(path, null, acl, CreateMode.PERSISTENT);
152 * Ensures that the given path exists with the given data, ACL and flags
154 * @param path the lock path
155 * @param data the data
156 * @param acl list of ACLs applying to the path
157 * @param flags create mode flags
159 protected void ensureExists(final String path, final byte[] data, final List<ACL> acl,
160 final CreateMode flags) {
162 retryOperation(new ZooKeeperOperation() {
163 public boolean execute() throws KeeperException, InterruptedException {
164 Stat stat = zookeeper.exists(path, false);
168 zookeeper.create(path, data, acl, flags);
172 } catch (InterruptedException|KeeperException e) {
173 LOG.error(EELFLoggerDelegate.errorLogger,"Caught: " + e, e);
178 * Returns true if this protocol has been closed
180 * @return true if this protocol is closed
182 protected boolean isClosed() {
187 * Performs a retry delay if this is not the first attempt
189 * @param attemptCount the number of the attempts performed so far
191 protected void retryDelay(int attemptCount) {
192 if (attemptCount > 0) {
194 Thread.sleep(attemptCount * retryDelay);
195 } catch (InterruptedException e) {
196 LOG.error(EELFLoggerDelegate.errorLogger,"Failed to sleep: " + e, e);
197 Thread.currentThread().interrupt();