Cleanup: use Java 8 lambdas
[netvirt.git] / openstack / net-virt-sfc / impl / src / main / java / org / opendaylight / netvirt / openstack / netvirt / sfc / DelegatingDataTreeListener.java
1 /*
2  * Copyright (c) 2013, 2016 Dell, 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
9 package org.opendaylight.netvirt.openstack.netvirt.sfc;
10
11 import java.util.Collection;
12 import java.util.concurrent.ExecutorService;
13 import java.util.concurrent.Executors;
14 import java.util.concurrent.ThreadFactory;
15
16 import javax.annotation.Nonnull;
17
18 import com.google.common.base.Preconditions;
19 import com.google.common.util.concurrent.ThreadFactoryBuilder;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
22 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
23 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
24 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
25 import org.opendaylight.yangtools.concepts.ListenerRegistration;
26 import org.opendaylight.yangtools.yang.binding.DataObject;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Data-tree listener which delegates data processing to a {@link INetvirtSfcDataProcessor}.
33  */
34 public class DelegatingDataTreeListener<T extends DataObject> implements AutoCloseable, DataTreeChangeListener<T> {
35     private static final Logger LOG = LoggerFactory.getLogger(DelegatingDataTreeListener.class);
36     protected INetvirtSfcOF13Provider provider;
37     private static final ThreadFactory threadFactory = new ThreadFactoryBuilder()
38         .setNameFormat("NV-SfcDTL-%d").build();
39     private final ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);
40     private final INetvirtSfcDataProcessor<T> dataProcessor;
41     private ListenerRegistration<DelegatingDataTreeListener<T>> listenerRegistration;
42
43     public DelegatingDataTreeListener(INetvirtSfcOF13Provider provider, INetvirtSfcDataProcessor<T> dataProcessor,
44                                       DataBroker db, DataTreeIdentifier<T> treeId) {
45         this.provider = Preconditions.checkNotNull(provider, "provider can not be null!");
46         this.dataProcessor = Preconditions.checkNotNull(dataProcessor, "Data processor can not be null!");
47         registerListener(Preconditions.checkNotNull(db, "Data broker can not be null!"),
48                 Preconditions.checkNotNull(treeId, "Tree identifier can not be null!"));
49     }
50
51     private void registerListener(final DataBroker db, DataTreeIdentifier<T> treeId) {
52         try {
53             LOG.info("Registering Data Change Listener for {}", getClass().getSimpleName());
54             listenerRegistration = db.registerDataTreeChangeListener(treeId, this);
55         } catch (final Exception e) {
56             LOG.warn("{} DataChange listener registration fail!", getClass().getSimpleName(), e);
57             throw new IllegalStateException("DataTreeListener startup fail! System needs restart.", e);
58         }
59     }
60
61     private void processChanges(Collection<DataTreeModification<T>> changes) {
62         LOG.info("onDataTreeChanged: Received Data Tree Changed ...", changes);
63         for (DataTreeModification<T> change : changes) {
64             final InstanceIdentifier<T> key = change.getRootPath().getRootIdentifier();
65             final DataObjectModification<T> mod = change.getRootNode();
66             LOG.info("onDataTreeChanged: Received Data Tree Changed Update of Type={} for Key={}",
67                     mod.getModificationType(), key);
68             switch (mod.getModificationType()) {
69                 case DELETE:
70                     dataProcessor.remove(key, mod.getDataBefore());
71                     break;
72                 case SUBTREE_MODIFIED:
73                     dataProcessor.update(key, mod.getDataBefore(), mod.getDataAfter());
74                     break;
75                 case WRITE:
76                     if (mod.getDataBefore() == null) {
77                         dataProcessor.add(key, mod.getDataAfter());
78                     } else {
79                         dataProcessor.update(key, mod.getDataBefore(), mod.getDataAfter());
80                     }
81                     break;
82                 default:
83                     throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
84             }
85         }
86     }
87
88     @Override
89     public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<T>> changes) {
90         Preconditions.checkNotNull(changes, "Changes may not be null!");
91         executorService.submit(() -> processChanges(changes));
92     }
93
94     @Override
95     public void close() {
96         if (listenerRegistration != null) {
97             listenerRegistration.close();
98             listenerRegistration = null;
99         }
100     }
101 }