]> git.basschouten.com Git - openhab-addons.git/blob
33e476689c5058e759fb3d43b46d06673cffb429
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.Comparator;
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.Predicate;
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.UniFiClient;
27 import org.openhab.binding.unifi.internal.api.dto.UniFiDevice;
28 import org.openhab.binding.unifi.internal.api.dto.UniFiPortTuple;
29 import org.openhab.binding.unifi.internal.api.dto.UniFiSite;
30 import org.openhab.binding.unifi.internal.api.dto.UniFiSwitchPorts;
31 import org.openhab.binding.unifi.internal.api.dto.UniFiVoucher;
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  * @author Mark Herwege - Added guest vouchers
42  */
43 @NonNullByDefault
44 public class UniFiControllerCache {
45
46     private final Logger logger = LoggerFactory.getLogger(UniFiControllerCache.class);
47
48     private final UniFiSiteCache sitesCache = new UniFiSiteCache();
49     private final UniFiWlanCache wlansCache = new UniFiWlanCache();
50     private final UniFiDeviceCache devicesCache = new UniFiDeviceCache();
51     private final UniFiClientCache clientsCache = new UniFiClientCache();
52     private final UniFiClientCache insightsCache = new UniFiClientCache();
53     private final UniFiVoucherCache vouchersCache = new UniFiVoucherCache();
54     private final Map<String, UniFiSwitchPorts> devicesToPortTables = new ConcurrentHashMap<>();
55
56     public void clear() {
57         sitesCache.clear();
58         wlansCache.clear();
59         devicesCache.clear();
60         clientsCache.clear();
61         insightsCache.clear();
62         vouchersCache.clear();
63     }
64
65     // Sites Cache
66
67     public List<UniFiSite> setSites(final UniFiSite @Nullable [] sites) {
68         sitesCache.putAll(sites);
69         return List.of(sites);
70     }
71
72     public @Nullable UniFiSite getSite(final @Nullable String id) {
73         return sitesCache.get(id);
74     }
75
76     public Collection<UniFiSite> getSites() {
77         return sitesCache.values();
78     }
79
80     // Wlans Cache
81
82     public void putWlans(final UniFiWlan @Nullable [] wlans) {
83         wlansCache.putAll(wlans);
84     }
85
86     public @Nullable UniFiWlan getWlan(@Nullable final String id) {
87         return wlansCache.get(id);
88     }
89
90     public Collection<UniFiWlan> getWlans() {
91         return wlansCache.values();
92     }
93
94     // Devices Cache
95
96     public void putDevices(final UniFiDevice @Nullable [] devices) {
97         devicesCache.putAll(devices);
98         if (devices != null) {
99             Stream.of(devices).filter(Objects::nonNull).forEach(d -> {
100                 Stream.ofNullable(d.getPortTable()).forEach(pt -> {
101                     final UniFiSwitchPorts switchPorts = devicesToPortTables.computeIfAbsent(d.getMac(),
102                             p -> new UniFiSwitchPorts());
103
104                     Stream.of(pt).forEach(p -> {
105                         @SuppressWarnings("null")
106                         final UniFiPortTuple tuple = switchPorts.computeIfAbsent(p.getPortIdx());
107
108                         tuple.setDevice(d);
109                         tuple.setTable(p);
110                     });
111                 });
112                 Stream.ofNullable(d.getPortOverrides()).forEach(po -> {
113                     final UniFiSwitchPorts tupleTable = devicesToPortTables.get(d.getMac());
114
115                     if (tupleTable != null) {
116                         Stream.of(po).forEach(p -> tupleTable.setOverride(p));
117                     }
118                 });
119             });
120         }
121     }
122
123     public @Nullable UniFiDevice getDevice(@Nullable final String id) {
124         return devicesCache.get(id);
125     }
126
127     public UniFiSwitchPorts getSwitchPorts(@Nullable final String deviceId) {
128         return deviceId == null ? new UniFiSwitchPorts()
129                 : devicesToPortTables.getOrDefault(deviceId, new UniFiSwitchPorts());
130     }
131
132     public Collection<UniFiSwitchPorts> getSwitchPorts() {
133         return devicesToPortTables.values();
134     }
135
136     // Clients Cache
137
138     public void putClients(final UniFiClient @Nullable [] clients) {
139         clientsCache.putAll(clients);
140     }
141
142     public Collection<UniFiClient> getClients() {
143         return clientsCache.values();
144     }
145
146     public long countClients(final UniFiSite site, final Predicate<UniFiClient> filter) {
147         return getClients().stream().filter(c -> site.isSite(c.getSite())).filter(filter::test).count();
148     }
149
150     public @Nullable UniFiClient getClient(@Nullable final String cid) {
151         UniFiClient client = null;
152         if (cid != null && !cid.isBlank()) {
153             synchronized (this) {
154                 // mgb: first check active clients and fallback to insights if not found
155                 client = clientsCache.get(cid);
156                 if (client == null) {
157                     final String id = clientsCache.getId(cid);
158
159                     client = insightsCache.get(id == null ? cid : id);
160                 }
161             }
162             if (client == null) {
163                 logger.debug("Could not find a matching client for cid = {}", cid);
164             }
165         }
166         return client;
167     }
168
169     public synchronized Stream<UniFiClient> getClientStreamForSite(final UniFiSite site) {
170         return clientsCache.values().stream().filter(client -> client.getSite().equals(site));
171     }
172
173     // Insights Cache
174
175     public void putInsights(final UniFiClient @Nullable [] insights) {
176         insightsCache.putAll(insights);
177     }
178
179     // Vouchers Cache
180
181     public void putVouchers(final UniFiVoucher @Nullable [] vouchers) {
182         vouchersCache.putAll(vouchers);
183     }
184
185     public synchronized Stream<UniFiVoucher> getVoucherStreamForSite(final UniFiSite site) {
186         return vouchersCache.values().stream().filter(voucher -> voucher.getSite().equals(site));
187     }
188
189     public @Nullable UniFiVoucher getVoucher(final UniFiSite site) {
190         // Use one of the oldest vouchers first
191         return getVoucherStreamForSite(site).min(Comparator.comparing(UniFiVoucher::getCreateTime)).orElse(null);
192     }
193 }