Adding BC group update job.
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / internal / ElanGroupCache.java
1 /*
2  * Copyright (c) 2019 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.netvirt.elan.internal;
10
11 import com.google.common.base.Optional;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Map;
15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.TimeUnit;
17
18 import javax.annotation.PostConstruct;
19 import javax.inject.Inject;
20 import javax.inject.Singleton;
21
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
26 import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
27 import org.opendaylight.netvirt.elan.utils.Scheduler;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 @Singleton
37 public class ElanGroupCache extends AsyncClusteredDataTreeChangeListenerBase<Group, ElanGroupCache> {
38     private static final Logger LOG = LoggerFactory.getLogger(ElanGroupCache.class);
39     private final DataBroker dataBroker;
40     private final Scheduler scheduler;
41     private final Map<InstanceIdentifier<Group>, Group> groupsById = new ConcurrentHashMap<>();
42     private final Map<InstanceIdentifier<Group>, Collection<Runnable>> waitingJobs = new ConcurrentHashMap<>();
43
44     @Inject
45     public ElanGroupCache(final DataBroker dataBroker, final Scheduler scheduler) {
46         super(Group.class, ElanGroupCache.class);
47         this.dataBroker = dataBroker;
48         this.scheduler = scheduler;
49     }
50
51     @PostConstruct
52     public synchronized void init() {
53         this.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
54     }
55
56     @Override
57     protected InstanceIdentifier<Group> getWildCardPath() {
58         return InstanceIdentifier.builder(Nodes.class)
59                 .child(Node.class).augmentation(FlowCapableNode.class)
60                 .child(Group.class).build();
61     }
62
63     public synchronized void addJobToWaitList(InstanceIdentifier<Group> key,
64                                               Runnable job) {
65         if (groupsById.containsKey(key)) {
66             job.run();
67         } else {
68             waitingJobs.putIfAbsent(key, new ArrayList<>());
69             waitingJobs.get(key).add(job);
70         }
71     }
72
73     @Override
74     protected ElanGroupCache getDataTreeChangeListener() {
75         return ElanGroupCache.this;
76     }
77
78     @Override
79     protected synchronized void remove(InstanceIdentifier<Group> key, Group deleted) {
80         groupsById.remove(key);
81     }
82
83     @Override
84     protected void update(InstanceIdentifier<Group> key, Group old, Group updated) {
85         add(key, updated);
86     }
87
88     @Override
89     protected synchronized void add(InstanceIdentifier<Group> key, Group added) {
90         if (groupsById.containsKey(key)) {
91             groupsById.put(key, added);
92             return;
93         }
94         scheduler.getScheduledExecutorService().schedule(() -> {
95             groupsById.put(key, added);
96             Collection<Runnable> jobs = waitingJobs.remove(key);
97             if (jobs == null) {
98                 return;
99             }
100             for (Runnable job : jobs) {
101                 job.run();
102             }
103         }, ElanInterfaceManager.WAIT_TIME_FOR_SYNC_INSTALL, TimeUnit.MILLISECONDS);
104     }
105
106     public Optional<Group> getGroup(InstanceIdentifier<Group> key) throws ReadFailedException {
107         if (groupsById.containsKey(key)) {
108             return Optional.of(groupsById.get(key));
109         }
110         ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction();
111         Optional<Group> optional = transaction.read(LogicalDatastoreType.CONFIGURATION, key).checkedGet();
112         transaction.close();
113         return optional;
114     }
115 }