2 * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
11 import java.util.List;
13 import java.util.Optional;
14 import java.util.function.BiPredicate;
15 import java.util.function.Predicate;
17 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
18 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
19 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
20 import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
21 import org.opendaylight.yangtools.yang.binding.DataObject;
22 import org.opendaylight.yangtools.yang.binding.Identifiable;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 public abstract class DependentJob<T extends Identifiable> {
29 private static final Logger LOG = LoggerFactory.getLogger(DependentJob.class);
31 private static final Predicate<HwvtepDeviceInfo.DeviceData> DATA_INTRANSIT
32 = (controllerData) -> controllerData != null && controllerData.isInTransitState();
34 private static final Predicate<HwvtepDeviceInfo.DeviceData> DATA_INTRANSIT_EXPIRED
35 = (controllerData) -> controllerData != null && controllerData.isInTransitState()
36 && controllerData.isIntransitTimeExpired();
38 //expecting the device to create the data
39 private static final BiPredicate<HwvtepDeviceInfo.DeviceData, Optional<TypedBaseTable>> INTRANSIT_DATA_CREATED
40 = (controllerData, deviceData) -> controllerData.getUuid() == null && deviceData.isPresent();
42 private static final BiPredicate<HwvtepDeviceInfo.DeviceData, Optional<TypedBaseTable>> INTRANSIT_DATA_NOT_CREATED
43 = (controllerData, deviceData) -> controllerData.getUuid() == null && !deviceData.isPresent();
45 //expecting the device to delete the data
46 private static final BiPredicate<HwvtepDeviceInfo.DeviceData, Optional<TypedBaseTable>> INTRANSIT_DATA_DELETED
47 = (controllerData, deviceData) -> controllerData.getUuid() != null && !deviceData.isPresent();
49 private static final BiPredicate<HwvtepDeviceInfo.DeviceData, Optional<TypedBaseTable>> INTRANSIT_DATA_NOT_DELETED
50 = (controllerData, deviceData) -> controllerData.getUuid() != null && deviceData.isPresent();
52 private final long expiryTime;
53 private final InstanceIdentifier key;
55 private final Map<Class<? extends DataObject>, List<InstanceIdentifier>> dependencies;
57 DependentJob(InstanceIdentifier key,
58 T data, Map<Class<? extends DataObject>, List<InstanceIdentifier>> dependencies) {
59 this.expiryTime = System.currentTimeMillis() + HwvtepSouthboundConstants.WAITING_JOB_EXPIRY_TIME_MILLIS;
62 this.dependencies = dependencies;
66 * This call back method gets called when all its dependencies are resolved
67 * @param operationalState new current operational state
68 * @param transactionBuilder transaction builder to create device transaction
70 protected abstract void onDependencyResolved(HwvtepOperationalState operationalState,
71 TransactionBuilder transactionBuilder);
74 * This method is to check if all the given dependency of this job or not
75 * @param deviceInfo The device info of tis job
76 * @param cls dependency type to be checked for
77 * @param iid instance identifier to be checked for
78 * @return true if the dependency is met
80 protected abstract boolean isDependencyMet(HwvtepDeviceInfo deviceInfo, Class<? extends DataObject> cls,
81 InstanceIdentifier iid);
83 boolean isExpired(long currentTime) {
84 return currentTime > expiryTime;
88 * This method checks if all the dependencies of this job or met or not
89 * @param deviceInfo The device info of this job
90 * @return true if all the dependencies are met
92 boolean areDependenciesMet(HwvtepDeviceInfo deviceInfo) {
93 for (Class<? extends DataObject> cls : dependencies.keySet()) {
94 for (InstanceIdentifier iid : dependencies.get(cls)) {
95 if (!isDependencyMet(deviceInfo, cls, iid)) {
103 public InstanceIdentifier getKey() {
111 public boolean isConfigWaitingJob() {
115 public void onFailure(TransactionBuilder deviceTransaction) {
118 public void onSuccess(TransactionBuilder deviceTransaction) {
121 public abstract static class ConfigWaitingJob<T extends Identifiable> extends DependentJob {
123 public ConfigWaitingJob(InstanceIdentifier key, T data, Map dependencies) {
124 super(key, data, dependencies);
128 protected boolean isDependencyMet(HwvtepDeviceInfo deviceInfo, Class cls, InstanceIdentifier iid) {
129 return deviceInfo.isConfigDataAvailable(cls, iid);
133 public abstract static class OpWaitingJob<T extends Identifiable> extends DependentJob {
135 public OpWaitingJob(InstanceIdentifier key, T data, Map dependencies) {
136 super(key, data, dependencies);
140 protected boolean isDependencyMet(HwvtepDeviceInfo deviceInfo, Class cls, InstanceIdentifier iid) {
141 boolean depenencyMet = true;
142 HwvtepDeviceInfo.DeviceData controllerData = deviceInfo.getDeviceOperData(cls, iid);
144 if (DATA_INTRANSIT_EXPIRED.test(controllerData)) {
145 LOG.info("Intransit state expired for key: {} --- dependency {}", iid, getKey());
146 String clsName = cls.getSimpleName();
148 //either the device acted on the selected iid/uuid and sent the updated event or it did not
149 //here we are querying the device directly to get the latest status on the iid
150 Optional<TypedBaseTable> latestDeviceStatus = deviceInfo.getConnectionInstance().
151 getHwvtepTableReader().getHwvtepTableEntryUUID(cls, iid, controllerData.getUuid());
153 TypedBaseTable latestDeviceData = latestDeviceStatus.isPresent() ? latestDeviceStatus.get() : null;
155 if (INTRANSIT_DATA_CREATED.test(controllerData, latestDeviceStatus)) {
156 LOG.info("Intransit expired key is actually created but update is missed/delayed {}", iid);
157 deviceInfo.updateDeviceOperData(cls, iid, latestDeviceStatus.get().getUuid(), latestDeviceData);
159 } else if (INTRANSIT_DATA_NOT_CREATED.test(controllerData, latestDeviceStatus)) {
160 LOG.info("Intransit expired key is actually not created but update is missed/delayed {}", iid);
161 deviceInfo.clearDeviceOperData(cls, iid);
163 } else if (INTRANSIT_DATA_DELETED.test(controllerData, latestDeviceStatus)) {
164 //also deleted from device
165 LOG.info("Intransit expired key is actually deleted but update is missed/delayed {}", iid);
166 deviceInfo.clearDeviceOperData(cls, iid);
168 } else if (INTRANSIT_DATA_NOT_DELETED.test(controllerData, latestDeviceStatus)) {
169 //not deleted from device we will reuse existing uuid
170 LOG.info("Intransit expired key is actually not deleted but update is missed/delayed {}", iid);
171 deviceInfo.updateDeviceOperData(cls, iid, latestDeviceStatus.get().getUuid(), latestDeviceData);
173 } else if (DATA_INTRANSIT.test(controllerData)) {
174 //device status is still in transit
175 depenencyMet = false;
180 public boolean isConfigWaitingJob() {