a1e3f2d0b5fc5d3c7b50ba480d976921a5cd163f
[ovsdb.git] / southbound / southbound-impl / src / main / java / org / opendaylight / ovsdb / southbound / reconciliation / ReconciliationTask.java
1 /*
2  * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.ovsdb.southbound.reconciliation;
9
10 import com.google.common.base.Preconditions;
11 import org.opendaylight.ovsdb.southbound.OvsdbConnectionManager;
12 import org.opendaylight.ovsdb.southbound.reconciliation.connection.ConnectionReconciliationTask;
13 import org.opendaylight.yangtools.yang.binding.DataObject;
14 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 /**
19  * Abstract implementation of a reconciliation task. Each new type of
20  * resource configuration reconciliation task should extend this class
21  * and implement the abstract methods.
22  * Created by Anil Vishnoi (avishnoi@Brocade.com) on 3/9/16.
23  */
24 public abstract class ReconciliationTask implements Runnable {
25
26     private static final Logger LOG = LoggerFactory.getLogger(ReconciliationTask.class);
27
28     protected final ReconciliationManager reconciliationManager;
29     protected final OvsdbConnectionManager connectionManager;
30     protected final InstanceIdentifier<?> nodeIid;
31     protected final DataObject configData;
32
33     protected ReconciliationTask(ReconciliationManager reconciliationManager, OvsdbConnectionManager connectionManager,
34                                  InstanceIdentifier<?> nodeIid,
35                                  DataObject configData) {
36         Preconditions.checkNotNull(reconciliationManager, "Reconciliation manager must not be null");
37         Preconditions.checkNotNull(connectionManager, "Connection manager must not be null");
38         Preconditions.checkNotNull(nodeIid, "Node Iid must not be null");
39         this.reconciliationManager = reconciliationManager;
40         this.connectionManager = connectionManager;
41         this.nodeIid = nodeIid;
42         this.configData = configData;
43     }
44
45     /**
46      * Method contains task reconciliation logic. Please refer to
47      * {@link ConnectionReconciliationTask#reconcileConfiguration(OvsdbConnectionManager)}
48      * for example.
49      * @param connectionManager Connection manager to get connection instance of the device
50      * @return True if reconciliation was successful, else false
51      */
52     public abstract boolean reconcileConfiguration(OvsdbConnectionManager connectionManager);
53
54     /**
55      * Extended task should implement the logic that decides whether retry for the task
56      * is required or not. If retry is required but it does not requires any delay, submit
57      * the task immediately using {@link ReconciliationManager#enqueue(ReconciliationTask)}.
58      * If retry requires delay, use {@link ReconciliationManager#enqueueForRetry(ReconciliationTask)}
59      * and specify the delay using {@link #retryDelayInMills()}.
60      * If data store operation is required to decide if the task need retry, please implement
61      * it as an async operation and submit the task on the callback of the future.
62      * <p>
63      * Note:Please do not write blocking data store operations
64      * {@link ConnectionReconciliationTask#doRetry(boolean)}
65      * </p>
66      * @param wasPreviousAttemptSuccessful Status of the previous attempt
67      */
68     public abstract void doRetry(boolean wasPreviousAttemptSuccessful);
69
70     /**
71      * Extended task should implement the logic that check the readiness of the task
72      * for execution. If task is ready for the execution, submit it for immediate
73      * execution using {@link ReconciliationManager#enqueue(ReconciliationTask)}.
74      * If task is not ready for execution yet, enqueue it again for delayed execution
75      * using {@link ReconciliationManager#enqueueForRetry(ReconciliationTask)}.
76      * To check the readiness of the task, if the data store operation is required, please
77      * implement it as an async operation and submit the task on the callback of the future.
78      * <p>
79      * Note:Please do not write blocking data store operations
80      * {@link ConnectionReconciliationTask#doRetry(boolean)}
81      * </p>
82      */
83     public abstract void checkReadinessAndProcess();
84
85     /**
86      * Method returns the time interval for retrying the failed task.
87      * {@link ReconciliationTask#doRetry(boolean)}
88      * @return time
89      */
90     public abstract long retryDelayInMills();
91
92     @Override
93     public void run() {
94         boolean status = this.reconcileConfiguration(connectionManager);
95         doRetry(status);
96     }
97
98     @Override
99     public boolean equals(Object o) {
100         if (this == o) return true;
101         if (o == null || getClass() != o.getClass()) {
102             return false;
103         }
104
105         ReconciliationTask that = (ReconciliationTask) o;
106
107         return nodeIid.equals(that.nodeIid);
108
109     }
110
111     @Override
112     public int hashCode() {
113         return getClass().hashCode() + nodeIid.hashCode();
114     }
115
116
117     @Override
118     public String toString() {
119         return "ReconciliationTask{ type=" + getClass().toString()+
120                 ", nodeIid=" + nodeIid +
121                 '}';
122     }
123 }