]> git.basschouten.com Git - openhab-addons.git/blob
698cb42b8fb2b676f10c2704bc5d3fb6ae15fca7
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.unifi.internal.api.cache;
14
15 import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Objects;
20 import java.util.concurrent.ConcurrentHashMap;
21 import java.util.function.Function;
22 import java.util.stream.Stream;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverrideJsonElement;
27 import org.openhab.binding.unifi.internal.api.dto.UniFiClient;
28 import org.openhab.binding.unifi.internal.api.dto.UniFiDevice;
29 import org.openhab.binding.unifi.internal.api.dto.UniFiPortTable;
30 import org.openhab.binding.unifi.internal.api.dto.UniFiPortTuple;
31 import org.openhab.binding.unifi.internal.api.dto.UniFiSite;
32 import org.openhab.binding.unifi.internal.api.dto.UniFiWlan;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * Class to manager cache for the controller keeping track of all specific cache objects.
38  *
39  * @author Matthew Bowman - Initial contribution
40  * @author Hilbrand Bouwkamp - Moved cache to this dedicated class.
41  */
42 @NonNullByDefault
43 public class UniFiControllerCache {
44
45     private final Logger logger = LoggerFactory.getLogger(UniFiControllerCache.class);
46
47     private final UniFiSiteCache sitesCache = new UniFiSiteCache();
48     private final UniFiWlanCache wlansCache = new UniFiWlanCache();
49     private final UniFiDeviceCache devicesCache = new UniFiDeviceCache();
50     private final UniFiClientCache clientsCache = new UniFiClientCache();
51     private final UniFiClientCache insightsCache = new UniFiClientCache();
52     private final Map<String, Map<Integer, UniFiPortTuple>> devicesToPortTables = new ConcurrentHashMap<>();
53
54     public void clear() {
55         sitesCache.clear();
56         wlansCache.clear();
57         devicesCache.clear();
58         clientsCache.clear();
59         insightsCache.clear();
60     }
61
62     // Sites Cache
63
64     public List<UniFiSite> setSites(final UniFiSite @Nullable [] sites) {
65         sitesCache.putAll(sites);
66         return List.of(sites);
67     }
68
69     public @Nullable UniFiSite getSite(final @Nullable String id) {
70         return sitesCache.get(id);
71     }
72
73     public Collection<UniFiSite> getSites() {
74         return sitesCache.values();
75     }
76
77     // Wlans Cache
78
79     public void putWlans(final UniFiWlan @Nullable [] wlans) {
80         wlansCache.putAll(wlans);
81     }
82
83     public @Nullable UniFiWlan getWlan(@Nullable final String id) {
84         return wlansCache.get(id);
85     }
86
87     public Collection<UniFiWlan> getWlans() {
88         return wlansCache.values();
89     }
90
91     // Devices Cache
92
93     public void putDevices(final UniFiDevice @Nullable [] devices) {
94         devicesCache.putAll(devices);
95         if (devices != null) {
96             Stream.of(devices).filter(Objects::nonNull).forEach(d -> {
97                 Stream.ofNullable(d.getPortTable()).flatMap(pt -> Stream.of(pt)).filter(UniFiPortTable::isPortPoe)
98                         .forEach(p -> {
99                             final Map<Integer, UniFiPortTuple> tupleTable = devicesToPortTables
100                                     .computeIfAbsent(d.getMac(), tt -> new HashMap<>());
101                             final UniFiPortTuple tuple = tupleTable.computeIfAbsent(p.getPortIdx(),
102                                     t -> new UniFiPortTuple());
103
104                             tuple.setDevice(d);
105                             tuple.setTable(p);
106                         });
107                 Stream.ofNullable(d.getPortOverrides()).forEach(po -> {
108                     final Map<Integer, UniFiPortTuple> tupleTable = devicesToPortTables.get(d.getMac());
109
110                     if (tupleTable != null) {
111                         Stream.of(po).filter(pof -> !pof.getAsJsonObject().entrySet().isEmpty())
112                                 .map(UnfiPortOverrideJsonElement::new).forEach(p -> tupleTable
113                                         .computeIfAbsent(p.getPortIdx(), t -> new UniFiPortTuple()).setJsonElement(p));
114                     }
115                 });
116             });
117         }
118     }
119
120     public @Nullable UniFiDevice getDevice(@Nullable final String id) {
121         return devicesCache.get(id);
122     }
123
124     public Map<Integer, UniFiPortTuple> getSwitchPorts(@Nullable final String deviceId) {
125         return deviceId == null ? Map.of() : devicesToPortTables.getOrDefault(deviceId, Map.of());
126     }
127
128     public Collection<Map<Integer, UniFiPortTuple>> getSwitchPorts() {
129         return devicesToPortTables.values();
130     }
131
132     // Clients Cache
133
134     public void putClients(final UniFiClient @Nullable [] clients) {
135         clientsCache.putAll(clients);
136     }
137
138     public Collection<UniFiClient> getClients() {
139         return clientsCache.values();
140     }
141
142     public long countClients(final UniFiSite site, final Function<UniFiClient, Boolean> filter) {
143         return getClients().stream().filter(c -> site.isSite(c.getSite())).filter(filter::apply).count();
144     }
145
146     public @Nullable UniFiClient getClient(@Nullable final String cid) {
147         UniFiClient client = null;
148         if (cid != null && !cid.isBlank()) {
149             synchronized (this) {
150                 // mgb: first check active clients and fallback to insights if not found
151                 client = clientsCache.get(cid);
152                 if (client == null) {
153                     final String id = clientsCache.getId(cid);
154
155                     client = insightsCache.get(id == null ? cid : id);
156                 }
157             }
158             if (client == null) {
159                 logger.debug("Could not find a matching client for cid = {}", cid);
160             }
161         }
162         return client;
163     }
164
165     public synchronized Stream<UniFiClient> getClientStreamForSite(final UniFiSite site) {
166         return clientsCache.values().stream().filter(client -> client.getSite().equals(site));
167     }
168
169     // Insights Cache
170
171     public void putInsights(final UniFiClient @Nullable [] insights) {
172         insightsCache.putAll(insights);
173     }
174 }