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.Map.Entry;
14 import java.util.Optional;
15 import java.util.function.BiPredicate;
16 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;
56 private final long transactionId;
58 DependentJob(InstanceIdentifier key,
59 T data, Map<Class<? extends DataObject>, List<InstanceIdentifier>> dependencies,
61 this.expiryTime = System.currentTimeMillis() + HwvtepSouthboundConstants.WAITING_JOB_EXPIRY_TIME_MILLIS;
64 this.dependencies = dependencies;
65 this.transactionId = transactionId;
69 * This call back method gets called when all its dependencies are resolved.
71 * @param operationalState new current operational state
72 * @param transactionBuilder transaction builder to create device transaction
74 protected abstract void onDependencyResolved(HwvtepOperationalState operationalState,
75 TransactionBuilder transactionBuilder);
78 * This method is to check if all the given dependency of this job or not.
80 * @param deviceInfo The device info of tis job
81 * @param cls dependency type to be checked for
82 * @param iid instance identifier to be checked for
83 * @return true if the dependency is met
85 protected abstract boolean isDependencyMet(HwvtepDeviceInfo deviceInfo, Class<? extends DataObject> cls,
86 InstanceIdentifier iid);
88 boolean isExpired(long currentTime) {
89 return currentTime > expiryTime;
93 * This method checks if all the dependencies of this job or met or not.
95 * @param deviceInfo The device info of this job
96 * @return true if all the dependencies are met
98 boolean areDependenciesMet(HwvtepDeviceInfo deviceInfo) {
99 for (Entry<Class<? extends DataObject>, List<InstanceIdentifier>> entry : dependencies.entrySet()) {
100 Class<? extends DataObject> cls = entry.getKey();
101 for (InstanceIdentifier<?> iid : entry.getValue()) {
102 if (!isDependencyMet(deviceInfo, cls, iid)) {
110 public InstanceIdentifier getKey() {
114 public long getTransactionId() {
115 return transactionId;
118 public Map<Class<? extends DataObject>, List<InstanceIdentifier>> getDependencies() {
126 public boolean isConfigWaitingJob() {
130 public void onFailure() {
133 public void onSuccess() {
136 public abstract static class ConfigWaitingJob<T extends Identifiable> extends DependentJob<T> {
138 public ConfigWaitingJob(InstanceIdentifier key, T data,
139 Map<Class<? extends DataObject>, List<InstanceIdentifier>> dependencies) {
140 super(key, data, dependencies, 0);
144 protected boolean isDependencyMet(HwvtepDeviceInfo deviceInfo, Class cls, InstanceIdentifier iid) {
145 return deviceInfo.isConfigDataAvailable(cls, iid);
148 public boolean isConfigWaitingJob() {
153 public abstract static class OpWaitingJob<T extends Identifiable> extends DependentJob<T> {
155 public OpWaitingJob(InstanceIdentifier key, T data,
156 Map<Class<? extends DataObject>, List<InstanceIdentifier>> dependencies,
157 long transactionId) {
158 super(key, data, dependencies, transactionId);
162 protected boolean isDependencyMet(HwvtepDeviceInfo deviceInfo, Class cls, InstanceIdentifier iid) {
163 boolean depenencyMet = true;
164 HwvtepDeviceInfo.DeviceData controllerData = deviceInfo.getDeviceOperData(cls, iid);
166 if (DATA_INTRANSIT_EXPIRED.test(controllerData)) {
167 LOG.info("Intransit state expired for key: {} --- dependency {}", iid, getKey());
169 //either the device acted on the selected iid/uuid and sent the updated event or it did not
170 //here we are querying the device directly to get the latest status on the iid
171 Optional<TypedBaseTable> latestDeviceStatus = deviceInfo.getConnectionInstance()
172 .getHwvtepTableReader().getHwvtepTableEntryUUID(cls, iid, controllerData.getUuid());
174 TypedBaseTable latestDeviceData = latestDeviceStatus.orElse(null);
176 if (INTRANSIT_DATA_CREATED.test(controllerData, latestDeviceStatus)) {
177 LOG.info("Intransit expired key is actually created but update is missed/delayed {}", iid);
178 deviceInfo.updateDeviceOperData(cls, iid, latestDeviceData.getUuid(), latestDeviceData);
180 } else if (INTRANSIT_DATA_NOT_CREATED.test(controllerData, latestDeviceStatus)) {
181 LOG.info("Intransit expired key is actually not created but update is missed/delayed {}", iid);
182 deviceInfo.clearDeviceOperData(cls, iid);
184 } else if (INTRANSIT_DATA_DELETED.test(controllerData, latestDeviceStatus)) {
185 //also deleted from device
186 LOG.info("Intransit expired key is actually deleted but update is missed/delayed {}", iid);
187 deviceInfo.clearDeviceOperData(cls, iid);
189 } else if (INTRANSIT_DATA_NOT_DELETED.test(controllerData, latestDeviceStatus)) {
190 //not deleted from device we will reuse existing uuid
191 LOG.info("Intransit expired key is actually not deleted but update is missed/delayed {}", iid);
192 deviceInfo.updateDeviceOperData(cls, iid, latestDeviceData.getUuid(), latestDeviceData);
194 } else if (DATA_INTRANSIT.test(controllerData)) {
195 //device status is still in transit
196 depenencyMet = false;
202 public boolean isConfigWaitingJob() {