46f73d1872379ad2edd310155ca6dac22d22ea5b
[openflowplugin.git] / applications / forwardingrules-manager / src / main / java / org / opendaylight / openflowplugin / applications / frm / impl / ListenerRegistrationHelper.java
1 /*
2  * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. 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.openflowplugin.applications.frm.impl;
10
11 import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.getInventoryConfigDataStoreStatus;
12
13 import com.google.common.util.concurrent.ListenableFuture;
14 import com.google.common.util.concurrent.ListeningExecutorService;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import com.google.common.util.concurrent.ThreadFactoryBuilder;
17 import java.util.concurrent.Executors;
18 import java.util.concurrent.TimeUnit;
19 import javax.inject.Inject;
20 import javax.inject.Singleton;
21 import org.apache.aries.blueprint.annotation.service.Reference;
22 import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
25 import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
26 import org.opendaylight.yangtools.concepts.ListenerRegistration;
27 import org.opendaylight.yangtools.yang.binding.DataObject;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31
32 @Singleton
33 public class ListenerRegistrationHelper {
34     private static final Logger LOG = LoggerFactory.getLogger(ListenerRegistrationHelper.class);
35     private static final long INVENTORY_CHECK_TIMER = 1;
36     private final String operational = "OPERATIONAL";
37     private final ListeningExecutorService listeningExecutorService;
38     private final DataBroker dataBroker;
39
40     @Inject
41     public ListenerRegistrationHelper(@Reference final DataBroker dataBroker) {
42         this.dataBroker = dataBroker;
43         listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(
44                  new ThreadFactoryBuilder()
45                 .setNameFormat("frm-listener" + "%d")
46                 .setDaemon(false)
47                 .setUncaughtExceptionHandler((thread, ex) -> LOG.error("Uncaught exception {}", thread, ex))
48                 .build()));
49     }
50
51     public <T extends DataObject, L extends ClusteredDataTreeChangeListener<T>>
52         ListenableFuture<ListenerRegistration<L>>
53         checkedRegisterListener(DataTreeIdentifier<T> treeId, L listener) {
54         return listeningExecutorService.submit(() -> {
55             while (! getInventoryConfigDataStoreStatus().equals(operational)) {
56                 try {
57                     LOG.debug("Retrying for datastore to become operational for listener {}", listener);
58                     Thread.sleep(INVENTORY_CHECK_TIMER * 1000);
59                 } catch (InterruptedException e) {
60                     LOG.info("registerDataTreeChangeListener thread is interrupted");
61                     Thread.currentThread().interrupt();
62                 }
63             }
64             SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(ForwardingRulesManagerImpl.STARTUP_LOOP_TICK,
65                     ForwardingRulesManagerImpl.STARTUP_LOOP_MAX_RETRIES);
66             return looper.loopUntilNoException(() -> dataBroker.registerDataTreeChangeListener(treeId, listener));
67         });
68     }
69
70     public void close() throws Exception {
71         MoreExecutors.shutdownAndAwaitTermination(listeningExecutorService, 5, TimeUnit.SECONDS);
72     }
73 }