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
8 package org.opendaylight.netvirt.elan.l2gw.ha.commands;
10 import static org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil.isEmptyList;
12 import java.io.Serializable;
13 import java.lang.reflect.ParameterizedType;
14 import java.lang.reflect.Type;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.Comparator;
18 import java.util.List;
19 import java.util.Objects;
20 import java.util.Optional;
21 import java.util.stream.Collectors;
22 import org.eclipse.jdt.annotation.NonNull;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
30 import org.opendaylight.yangtools.concepts.Builder;
31 import org.opendaylight.yangtools.yang.binding.DataObject;
32 import org.opendaylight.yangtools.yang.binding.Identifiable;
33 import org.opendaylight.yangtools.yang.binding.Identifier;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
41 public abstract class MergeCommand<T extends DataObject, Y extends Builder, Z extends DataObject>
42 extends BaseCommand<T> implements IMergeCommand<T, Y, Z> {
44 private static final Logger LOG = LoggerFactory.getLogger(MergeCommand.class);
46 Class<? extends Identifiable> classType = getType();
48 public List<T> transformOpData(List<T> existingData, List<T> src, InstanceIdentifier<Node> nodePath) {
49 List<T> added = diffOf(src, existingData);//do not add existing data again
50 return transform(nodePath, added);
53 public List<T> transformConfigData(List<T> updatedSrc, InstanceIdentifier<Node> nodePath) {
54 return transform(nodePath, updatedSrc);
58 public List<T> diffByKey(List<T> updated, final List<T> original) {
59 if (updated == null) {
60 return new ArrayList<>();
62 if (original == null) {
63 return new ArrayList<>(updated);
66 List<T> result = new ArrayList<>();
67 for (T ele : updated) {
68 boolean present = false;
69 for (T orig : original) {
70 if (Objects.equals(getKey(ele), getKey(orig))) {
82 Class<? extends Identifiable> getType() {
83 Type type = getClass().getGenericSuperclass();
84 return (Class<? extends Identifiable>)((ParameterizedType) type).getActualTypeArguments()[0];
88 <T extends DataObject> boolean isDataUpdated(Optional<T> existingDataOptional, T newData) {
89 return !existingDataOptional.isPresent() || !Objects.equals(existingDataOptional.get(), newData);
92 public List<T> transform(InstanceIdentifier<Node> nodePath, List<T> list) {
94 return list.stream().map(t -> transform(nodePath, t)).collect(Collectors.toList());
96 return new ArrayList<>();
99 public abstract T transform(InstanceIdentifier<Node> nodePath, T objT);
101 List<T> getDataSafe(Z existingData) {
102 if (existingData == null) {
103 return Collections.EMPTY_LIST;
105 List<T> result = getData(existingData);
106 if (result == null) {
107 return Collections.EMPTY_LIST;
113 public void mergeOperationalData(Y dst,
116 InstanceIdentifier<Node> nodePath) {
117 List<T> origDstData = getDataSafe(existingData);
118 List<T> srcData = getDataSafe(src);
119 List<T> data = transformOpData(origDstData, srcData, nodePath);
120 if (classType == RemoteUcastMacs.class) {
124 if (!isEmptyList(data)) {
125 String nodeId = nodePath.firstKeyOf(Node.class).getNodeId().getValue();
126 LOG.trace("merging op {} to {} size {}",getDescription(), nodeId, data.size());
131 public void mergeConfigData(Y dst,
133 InstanceIdentifier<Node> nodePath) {
134 List<T> data = getDataSafe(src);
135 List<T> transformed = transformConfigData(data, nodePath);
136 setData(dst, transformed);
137 if (!isEmptyList(data)) {
138 String nodeId = nodePath.firstKeyOf(Node.class).getNodeId().getValue();
139 LOG.trace("copying config {} to {} size {}",getDescription(), nodeId, data.size());
143 boolean areSameSize(@Nullable List objA,@Nullable List objB) {
144 if (HwvtepHAUtil.isEmptyList(objA) && HwvtepHAUtil.isEmptyList(objB)) {
147 if (!HwvtepHAUtil.isEmptyList(objA) && !HwvtepHAUtil.isEmptyList(objB)) {
148 return objA.size() == objB.size();
154 static LocatorSetComparator locatorSetComparator = new LocatorSetComparator();
156 static class LocatorSetComparator implements Comparator<LocatorSet>, Serializable {
157 private static final long serialVersionUID = 1L;
160 public int compare(final LocatorSet updatedLocatorSet, final LocatorSet origLocatorSet) {
161 InstanceIdentifier<?> updatedLocatorRefIndentifier = updatedLocatorSet.getLocatorRef().getValue();
162 TpId updatedLocatorSetTpId = updatedLocatorRefIndentifier.firstKeyOf(TerminationPoint.class).getTpId();
164 InstanceIdentifier<?> origLocatorRefIndentifier = origLocatorSet.getLocatorRef().getValue();
165 TpId origLocatorSetTpId = origLocatorRefIndentifier.firstKeyOf(TerminationPoint.class).getTpId();
167 if (updatedLocatorSetTpId.equals(origLocatorSetTpId)) {
175 public abstract List<T> getData(Z node);
177 public abstract void setData(Y builder, List<T> data);
179 public abstract InstanceIdentifier<T> generateId(InstanceIdentifier<Node> id, T node);
181 public abstract Identifier getKey(T data);
183 public abstract String getDescription();
185 public abstract T withoutUuid(T data);