/** * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.controller.frm.impl; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import org.opendaylight.controller.frm.ForwardingRulesCommiter; import org.opendaylight.controller.frm.ForwardingRulesManager; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import java.util.Collections; import java.util.Map; import java.util.Set; /** * AbstractChangeListner implemented basic {@link AsyncDataChangeEvent} processing for * flow node subDataObject (flows, groups and meters). * * @author Vaclav Demcak * */ public abstract class AbstractListeningCommiter implements ForwardingRulesCommiter { protected ForwardingRulesManager provider; protected final Class clazz; public AbstractListeningCommiter (ForwardingRulesManager provider, Class clazz) { this.provider = Preconditions.checkNotNull(provider, "ForwardingRulesManager can not be null!"); this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!"); } @Override public void onDataChanged(final AsyncDataChangeEvent, DataObject> changeEvent) { Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!"); /* All DataObjects for create */ final Map, DataObject> createdData = changeEvent.getCreatedData() != null ? changeEvent.getCreatedData() : Collections., DataObject> emptyMap(); /* All DataObjects for remove */ final Set> removeData = changeEvent.getRemovedPaths() != null ? changeEvent.getRemovedPaths() : Collections.> emptySet(); /* All DataObjects for updates */ final Map, DataObject> updateData = changeEvent.getUpdatedData() != null ? changeEvent.getUpdatedData() : Collections., DataObject> emptyMap(); /* All Original DataObjects */ final Map, DataObject> originalData = changeEvent.getOriginalData() != null ? changeEvent.getOriginalData() : Collections., DataObject> emptyMap(); this.createData(createdData); this.updateData(updateData, originalData); this.removeData(removeData, originalData); } /** * Method return wildCardPath for Listener registration * and for identify the correct KeyInstanceIdentifier from data; */ protected abstract InstanceIdentifier getWildCardPath(); @SuppressWarnings("unchecked") private void createData(final Map, DataObject> createdData) { final Set> keys = createdData.keySet() != null ? createdData.keySet() : Collections.> emptySet(); for (InstanceIdentifier key : keys) { if (clazz.equals(key.getTargetType())) { final InstanceIdentifier nodeIdent = key.firstIdentifierOf(FlowCapableNode.class); if (preConfigurationCheck(nodeIdent)) { InstanceIdentifier createKeyIdent = key.firstIdentifierOf(clazz); final Optional value = Optional.of(createdData.get(key)); if (value.isPresent()) { this.add(createKeyIdent, (T)value.get(), nodeIdent); } } } } } @SuppressWarnings("unchecked") private void updateData(final Map, DataObject> updateData, final Map, DataObject> originalData) { final Set> keys = updateData.keySet() != null ? updateData.keySet() : Collections.> emptySet(); for (InstanceIdentifier key : keys) { if (clazz.equals(key.getTargetType())) { final InstanceIdentifier nodeIdent = key.firstIdentifierOf(FlowCapableNode.class); if (preConfigurationCheck(nodeIdent)) { InstanceIdentifier updateKeyIdent = key.firstIdentifierOf(clazz); final Optional value = Optional.of(updateData.get(key)); final Optional original = Optional.of(originalData.get(key)); if (value.isPresent() && original.isPresent()) { this.update(updateKeyIdent, (T)original.get(), (T)value.get(), nodeIdent); } } } } } @SuppressWarnings("unchecked") private void removeData(final Set> removeData, final Map, DataObject> originalData) { for (InstanceIdentifier key : removeData) { if (clazz.equals(key.getTargetType())) { final InstanceIdentifier nodeIdent = key.firstIdentifierOf(FlowCapableNode.class); if (preConfigurationCheck(nodeIdent)) { final InstanceIdentifier ident = key.firstIdentifierOf(clazz); final DataObject removeValue = originalData.get(key); this.remove(ident, (T)removeValue, nodeIdent); } } } } private boolean preConfigurationCheck(final InstanceIdentifier nodeIdent) { Preconditions.checkNotNull(nodeIdent, "FlowCapableNode ident can not be null!"); return provider.isNodeActive(nodeIdent); } }