diff --git a/opensync-ext-cloud/src/main/java/com/telecominfraproject/wlan/opensync/external/integration/OpensyncExternalIntegrationCloud.java b/opensync-ext-cloud/src/main/java/com/telecominfraproject/wlan/opensync/external/integration/OpensyncExternalIntegrationCloud.java index 5e9641f..463fdd8 100644 --- a/opensync-ext-cloud/src/main/java/com/telecominfraproject/wlan/opensync/external/integration/OpensyncExternalIntegrationCloud.java +++ b/opensync-ext-cloud/src/main/java/com/telecominfraproject/wlan/opensync/external/integration/OpensyncExternalIntegrationCloud.java @@ -877,7 +877,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra LOG.info("OpensyncExternalIntegrationCloud::disconnectClients for Equipment {}", ce); PaginationResponse clientSessions = clientServiceInterface.getSessionsForCustomer( - ce.getCustomerId(), Set.of(ce.getId()), Set.of(ce.getLocationId()), null, + ce.getCustomerId(), Set.of(ce.getId()), Set.of(ce.getLocationId()), null, null, new PaginationContext(100)); if (clientSessions == null) { @@ -1859,7 +1859,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra List clientSessionsForCustomerAndEquipment = new ArrayList<>(); if (ce != null) { PaginationResponse clientSessions = clientServiceInterface.getSessionsForCustomer(customerId, - ImmutableSet.of(equipmentId), ImmutableSet.of(ce.getLocationId()), null, + ImmutableSet.of(equipmentId), ImmutableSet.of(ce.getLocationId()), null, null, new PaginationContext()); clientSessionsForCustomerAndEquipment.addAll(clientSessions.getItems()); } diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/mqtt/OpensyncMqttClient.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/mqtt/OpensyncMqttClient.java index 37fa9cc..150666f 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/mqtt/OpensyncMqttClient.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/mqtt/OpensyncMqttClient.java @@ -23,6 +23,15 @@ import com.google.protobuf.Descriptors; import com.google.protobuf.MessageOrBuilder; import com.google.protobuf.util.JsonFormat; import com.google.protobuf.util.JsonFormat.TypeRegistry; +import com.netflix.servo.DefaultMonitorRegistry; +import com.netflix.servo.monitor.BasicCounter; +import com.netflix.servo.monitor.BasicTimer; +import com.netflix.servo.monitor.Counter; +import com.netflix.servo.monitor.MonitorConfig; +import com.netflix.servo.monitor.Stopwatch; +import com.netflix.servo.monitor.Timer; +import com.netflix.servo.tag.TagList; +import com.telecominfraproject.wlan.cloudmetrics.CloudMetricsTags; import com.telecominfraproject.wlan.opensync.external.integration.OpensyncExternalIntegrationInterface; import com.telecominfraproject.wlan.opensync.util.ZlibUtil; @@ -43,9 +52,30 @@ public class OpensyncMqttClient implements ApplicationListener connectedClients = new ConcurrentHashMap<>(); + // dtop: use anonymous constructor to ensure that the following code always + // get executed, + // even when somebody adds another constructor in here + { + DefaultMonitorRegistry.getInstance().register(totalEquipmentConnectionsGauge); + } + @Override public OvsdbSession getSession(String apId) { LOG.info("Get session for AP {}", apId); @@ -29,7 +50,11 @@ public class OvsdbSessionMap implements OvsdbSessionMapInterface { @Override public OvsdbSession removeSession(String apId) { LOG.info("Removing session for AP {}", apId); - return connectedClients.remove(apId); + OvsdbSession ret = connectedClients.remove(apId); + if(ret!=null) { + totalEquipmentConnections.decrementAndGet(); + } + return ret; } @Override @@ -37,7 +62,7 @@ public class OvsdbSessionMap implements OvsdbSessionMapInterface { try { LOG.info("Close session for AP {}", apId); connectedClients.get(apId).getOvsdbClient().shutdown(); - connectedClients.remove(apId); + removeSession(apId); LOG.info("Closed ovsdb session for {}", apId); }catch (Exception e) { // do nothing @@ -58,6 +83,8 @@ public class OvsdbSessionMap implements OvsdbSessionMapInterface { }catch (Exception e) { // do nothing } + } else { + totalEquipmentConnections.incrementAndGet(); } LOG.info("Created new ovsdb session for {}", apId); diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbClient.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbClient.java index 5b8c146..1148af1 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbClient.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbClient.java @@ -1,6 +1,13 @@ package com.telecominfraproject.wlan.opensync.ovsdb; import com.google.common.collect.ImmutableMap; +import com.netflix.servo.DefaultMonitorRegistry; +import com.netflix.servo.monitor.BasicCounter; +import com.netflix.servo.monitor.Counter; +import com.netflix.servo.monitor.MonitorConfig; +import com.netflix.servo.monitor.Monitors; +import com.netflix.servo.tag.TagList; +import com.telecominfraproject.wlan.cloudmetrics.CloudMetricsTags; import com.telecominfraproject.wlan.core.model.equipment.MacAddress; import com.telecominfraproject.wlan.core.model.equipment.RadioType; import com.telecominfraproject.wlan.opensync.external.integration.OpensyncExternalIntegrationInterface; @@ -10,6 +17,8 @@ import com.telecominfraproject.wlan.opensync.external.integration.OvsdbSession; import com.telecominfraproject.wlan.opensync.external.integration.OvsdbSessionMapInterface; import com.telecominfraproject.wlan.opensync.external.integration.models.*; import com.telecominfraproject.wlan.opensync.ovsdb.dao.OvsdbDao; +import com.telecominfraproject.wlan.opensync.ovsdb.metrics.OvsdbClientWithMetrics; +import com.telecominfraproject.wlan.opensync.ovsdb.metrics.OvsdbMetrics; import com.telecominfraproject.wlan.opensync.util.OvsdbStringConstants; import com.telecominfraproject.wlan.opensync.util.SslUtil; import com.vmware.ovsdb.callback.ConnectionCallback; @@ -36,6 +45,21 @@ public class TipWlanOvsdbClient implements OvsdbClientInterface { private static final Logger LOG = LoggerFactory.getLogger(TipWlanOvsdbClient.class); + private final TagList tags = CloudMetricsTags.commonTags; + + private final Counter connectionsAttempted = new BasicCounter( + MonitorConfig.builder("osgw-connectionsAttempted").withTags(tags).build()); + + private final Counter connectionsFailed = new BasicCounter( + MonitorConfig.builder("osgw-connectionsFailed").withTags(tags).build()); + + private final Counter connectionsCreated = new BasicCounter( + MonitorConfig.builder("osgw-connectionsCreated").withTags(tags).build()); + + private final Counter connectionsDropped = new BasicCounter( + MonitorConfig.builder("osgw-connectionsDropped").withTags(tags).build()); + + @org.springframework.beans.factory.annotation.Value("${tip.wlan.ovsdb.listenPort:6640}") private int ovsdbListenPort; @@ -63,9 +87,22 @@ public class TipWlanOvsdbClient implements OvsdbClientInterface { @Autowired private OvsdbSessionMapInterface ovsdbSessionMapInterface; + @Autowired + private OvsdbMetrics ovsdbMetrics; + @org.springframework.beans.factory.annotation.Value("${tip.wlan.manager.collectionIntervalSec.event:60}") private long collectionIntervalSecEvent; + // dtop: use anonymous constructor to ensure that the following code always + // get executed, + // even when somebody adds another constructor in here + { + DefaultMonitorRegistry.getInstance().register(connectionsAttempted); + DefaultMonitorRegistry.getInstance().register(connectionsCreated); + DefaultMonitorRegistry.getInstance().register(connectionsDropped); + DefaultMonitorRegistry.getInstance().register(connectionsFailed); + } + @PostConstruct private void postCreate() { listenForConnections(); @@ -78,6 +115,12 @@ public class TipWlanOvsdbClient implements OvsdbClientInterface { @Override public void connected(OvsdbClient ovsdbClient) { + connectionsAttempted.increment(); + + if(! (ovsdbClient instanceof OvsdbClientWithMetrics )) { + ovsdbClient = new OvsdbClientWithMetrics(ovsdbClient, ovsdbMetrics); + } + String remoteHost = ovsdbClient.getConnectionInfo().getRemoteAddress().getHostAddress(); int localPort = ovsdbClient.getConnectionInfo().getLocalPort(); String subjectDn; @@ -102,14 +145,17 @@ public class TipWlanOvsdbClient implements OvsdbClientInterface { monitorOvsdbStateTables(ovsdbClient, key); + connectionsCreated.increment(); LOG.info("ovsdbClient connected from {} on port {} AP {} ", remoteHost, localPort, key); LOG.info("ovsdbClient connectedClients = {}", ovsdbSessionMapInterface.getNumSessions()); } catch (IllegalStateException e) { + connectionsFailed.increment(); LOG.error("autoprovisioning error {}", e.getMessage(), e); // something is wrong with the SSL ovsdbClient.shutdown(); } catch (Exception e) { + connectionsFailed.increment(); LOG.error("ovsdbClient error", e); // something is wrong with the SSL ovsdbClient.shutdown(); @@ -120,6 +166,8 @@ public class TipWlanOvsdbClient implements OvsdbClientInterface { @Override public void disconnected(OvsdbClient ovsdbClient) { + connectionsDropped.increment(); + String remoteHost; int localPort; String clientCn; diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbRedirector.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbRedirector.java index b24f383..9266963 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbRedirector.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbRedirector.java @@ -10,6 +10,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; +import com.netflix.servo.DefaultMonitorRegistry; +import com.netflix.servo.monitor.BasicCounter; +import com.netflix.servo.monitor.Counter; +import com.netflix.servo.monitor.MonitorConfig; +import com.netflix.servo.monitor.Monitors; +import com.netflix.servo.tag.TagList; +import com.telecominfraproject.wlan.cloudmetrics.CloudMetricsTags; import com.telecominfraproject.wlan.opensync.ovsdb.dao.OvsdbDao; import com.telecominfraproject.wlan.opensync.util.SslUtil; import com.vmware.ovsdb.callback.ConnectionCallback; @@ -24,6 +31,20 @@ public class TipWlanOvsdbRedirector { private static final Logger LOG = LoggerFactory.getLogger(TipWlanOvsdbRedirector.class); + private final TagList tags = CloudMetricsTags.commonTags; + + private final Counter connectionsAttempted = new BasicCounter( + MonitorConfig.builder("osgw-redirector-connectionsAttempted").withTags(tags).build()); + + private final Counter connectionsFailed = new BasicCounter( + MonitorConfig.builder("osgw-redirector-connectionsFailed").withTags(tags).build()); + + private final Counter connectionsCreated = new BasicCounter( + MonitorConfig.builder("osgw-redirector-connectionsCreated").withTags(tags).build()); + + private final Counter connectionsDropped = new BasicCounter( + MonitorConfig.builder("osgw-redirector-connectionsDropped").withTags(tags).build()); + @org.springframework.beans.factory.annotation.Value("${tip.wlan.ovsdb.redirector.listenPort:6643}") private int ovsdbRedirectorListenPort; @@ -41,10 +62,21 @@ public class TipWlanOvsdbRedirector { listenForConnections(); } + // dtop: use anonymous constructor to ensure that the following code always + // get executed, + // even when somebody adds another constructor in here + { + DefaultMonitorRegistry.getInstance().register(connectionsAttempted); + DefaultMonitorRegistry.getInstance().register(connectionsCreated); + DefaultMonitorRegistry.getInstance().register(connectionsDropped); + DefaultMonitorRegistry.getInstance().register(connectionsFailed); + } + public void listenForConnections() { ConnectionCallback connectionCallback = new ConnectionCallback() { public void connected(OvsdbClient ovsdbClient) { + connectionsAttempted.increment(); String remoteHost = ovsdbClient.getConnectionInfo().getRemoteAddress().getHostAddress(); int localPort = ovsdbClient.getConnectionInfo().getLocalPort(); String subjectDn = null; @@ -54,8 +86,9 @@ public class TipWlanOvsdbRedirector { String clientCn = SslUtil.extractCN(subjectDn); LOG.info("ovsdbClient redirector connected from {} on port {} clientCn {}", remoteHost, localPort, clientCn); ovsdbDao.performRedirect(ovsdbClient, clientCn); - + connectionsCreated.increment(); } catch (Exception e) { + connectionsFailed.increment(); //something is wrong with the SSL or with the redirect ovsdbClient.shutdown(); return; @@ -63,6 +96,7 @@ public class TipWlanOvsdbRedirector { } public void disconnected(OvsdbClient ovsdbClient) { + connectionsDropped.increment(); String remoteHost = ovsdbClient.getConnectionInfo().getRemoteAddress().getHostAddress(); int localPort = ovsdbClient.getConnectionInfo().getLocalPort(); String subjectDn = null; diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbRadioConfig.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbRadioConfig.java index 69d4ec2..f3a7b08 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbRadioConfig.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbRadioConfig.java @@ -33,24 +33,15 @@ public class OvsdbRadioConfig extends OvsdbDaoBase { OvsdbGet ovsdbGet; void configureWifiRadios(OvsdbClient ovsdbClient, OpensyncAPConfig opensyncAPConfig) { - String country = opensyncAPConfig.getCountryCode(); // should be the - // same for all - // radios on this AP - // ;-) - ApElementConfiguration apElementConfiguration = (ApElementConfiguration) opensyncAPConfig.getCustomerEquipment() .getDetails(); RfConfiguration rfConfig = (RfConfiguration) opensyncAPConfig.getRfProfile().getDetails(); - Map provisionedRadioConfigs = ovsdbGet.getProvisionedWifiRadioConfigs(ovsdbClient); Map vifConfigs = ovsdbGet.getProvisionedWifiVifConfigs(ovsdbClient); - List operations = new ArrayList<>(); - for (RadioType radioType : apElementConfiguration.getRadioMap().keySet()) { Map hwConfig = new HashMap<>(); - ElementRadioConfiguration elementRadioConfig = apElementConfiguration.getRadioMap().get(radioType); RfElementConfiguration rfElementConfig = rfConfig.getRfConfig(radioType); boolean autoChannelSelection = rfElementConfig.getAutoChannelSelection(); @@ -58,114 +49,19 @@ public class OvsdbRadioConfig extends OvsdbDaoBase { LOG.debug("configureWifiRadios autoChannelSelection {} activeChannel {} getChannelNumber {} ", autoChannelSelection, channel, elementRadioConfig.getChannelNumber()); ChannelBandwidth bandwidth = rfElementConfig.getChannelBandwidth(); - String ht_mode; - switch (bandwidth) { - case is20MHz: - ht_mode = "HT20"; - break; - case is40MHz: - ht_mode = "HT40"; - break; - case is80MHz: - ht_mode = "HT80"; - break; - case is160MHz: - ht_mode = "HT160"; - break; - case auto: - ht_mode = "0"; - break; - default: - ht_mode = null; - } - + String ht_mode = getBandwidth(bandwidth); RadioConfiguration radioConfig = apElementConfiguration.getAdvancedRadioMap().get(radioType); int beaconInterval = rfElementConfig.getBeaconInterval(); boolean enabled = radioConfig.getRadioAdminState().equals(StateSetting.enabled); - int txPower; if (elementRadioConfig.getEirpTxPower().getSource() == SourceType.profile) { txPower = rfElementConfig.getEirpTxPower(); } else { txPower = elementRadioConfig.getEirpTxPower().getValue(); } - - String hwMode = null; - switch (rfElementConfig.getRadioMode()) { - case modeA: - hwMode = "11a"; - break; - case modeAB: - hwMode = "11ab"; - break; - case modeAC: - hwMode = "11ac"; - break; - case modeB: - hwMode = "11b"; - break; - case modeG: - hwMode = "11g"; - break; - case modeAX: - hwMode = "11ax"; - break; - case modeN: - hwMode = "11n"; - break; - default: - } - String freqBand; - switch (radioType) { - case is2dot4GHz: - freqBand = "2.4G"; - break; - case is5GHz: - // 802.11h dfs (Dynamic Frequency Selection) aka military - // and - // weather radar - // avoidance protocol - // Must not be disabled (by law) - // NA for 2.4GHz - hwConfig.put("dfs_enable", "1"); - hwConfig.put("dfs_ignorecac", "0"); - hwConfig.put("dfs_usenol", "1"); - freqBand = "5G"; - - break; - case is5GHzL: - // 802.11h dfs (Dynamic Frequency Selection) aka military - // and - // weather radar - // avoidance protocol - // Must not be disabled (by law) - // NA for 2.4GHz - hwConfig.put("dfs_enable", "1"); - hwConfig.put("dfs_ignorecac", "0"); - hwConfig.put("dfs_usenol", "1"); - freqBand = "5GL"; - - break; - case is5GHzU: - // 802.11h dfs (Dynamic Frequency Selection) aka military - // and - // weather radar - // avoidance protocol - // Must not be disabled (by law) - // NA for 2.4GHz - hwConfig.put("dfs_enable", "1"); - hwConfig.put("dfs_ignorecac", "0"); - hwConfig.put("dfs_usenol", "1"); - freqBand = "5GU"; - - break; - default: // don't know this interface - continue; - - } - + String hwMode = getHwMode(rfElementConfig); + String freqBand = getHwConfigAndFreq(radioType, hwConfig); String radioName = null; - for (String key : provisionedRadioConfigs.keySet()) { if (provisionedRadioConfigs.get(key).freqBand.equals(freqBand)) { radioName = key; @@ -173,7 +69,6 @@ public class OvsdbRadioConfig extends OvsdbDaoBase { } } if (radioName == null) continue; - String ifName = null; // for vifConfigs if (radioName.equals(radio0)) { ifName = defaultRadio0; @@ -183,42 +78,36 @@ public class OvsdbRadioConfig extends OvsdbDaoBase { ifName = defaultRadio2; } if (ifName == null) continue; - Set vifUuidsForRadio = new HashSet<>(); for (String key : vifConfigs.keySet()) { if (key.contains(ifName)) vifUuidsForRadio.add(vifConfigs.get(key).uuid); } - int mimoMode = MimoMode.none.getId(); if (rfElementConfig.getMimoMode() != null) { mimoMode = rfElementConfig.getMimoMode().getId(); + } + int maxNumClients = 0; + if (rfElementConfig.getMaxNumClients() != null) { + maxNumClients = rfElementConfig.getMaxNumClients(); } - try { - configureWifiRadios(freqBand, channel, hwConfig, country.toUpperCase(), beaconInterval, - enabled, hwMode, ht_mode, txPower, mimoMode, vifUuidsForRadio, operations); + enabled, hwMode, ht_mode, txPower, mimoMode, vifUuidsForRadio, operations, maxNumClients); } catch (OvsdbClientException e) { LOG.error("ConfigureWifiRadios failed with OvsdbClient exception.", e); throw new RuntimeException(e); - } catch (TimeoutException e) { LOG.error("ConfigureWifiRadios failed with Timeout.", e); throw new RuntimeException(e); - } catch (ExecutionException e) { LOG.error("ConfigureWifiRadios excecution failed.", e); throw new RuntimeException(e); - } catch (InterruptedException e) { LOG.error("ConfigureWifiRadios interrupted.", e); throw new RuntimeException(e); - } - } - try { CompletableFuture fResult = ovsdbClient.transact(ovsdbName, operations); OperationResult[] result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS); @@ -231,14 +120,107 @@ public class OvsdbRadioConfig extends OvsdbDaoBase { } + String getHwConfigAndFreq(RadioType radioType, Map hwConfig) { + switch (radioType) { + case is2dot4GHz: + return "2.4G"; + case is5GHz: + // 802.11h dfs (Dynamic Frequency Selection) aka military + // and + // weather radar + // avoidance protocol + // Must not be disabled (by law) + // NA for 2.4GHz + hwConfig.put("dfs_enable", "1"); + hwConfig.put("dfs_ignorecac", "0"); + hwConfig.put("dfs_usenol", "1"); + return "5G"; + case is5GHzL: + // 802.11h dfs (Dynamic Frequency Selection) aka military + // and + // weather radar + // avoidance protocol + // Must not be disabled (by law) + // NA for 2.4GHz + hwConfig.put("dfs_enable", "1"); + hwConfig.put("dfs_ignorecac", "0"); + hwConfig.put("dfs_usenol", "1"); + return "5GL"; + case is5GHzU: + // 802.11h dfs (Dynamic Frequency Selection) aka military + // and + // weather radar + // avoidance protocol + // Must not be disabled (by law) + // NA for 2.4GHz + hwConfig.put("dfs_enable", "1"); + hwConfig.put("dfs_ignorecac", "0"); + hwConfig.put("dfs_usenol", "1"); + return "5GU"; + default: // don't know this interface + return null; + } + } + + private String getBandwidth(ChannelBandwidth bandwidth) { + String ht_mode; + switch (bandwidth) { + case is20MHz: + ht_mode = "HT20"; + break; + case is40MHz: + ht_mode = "HT40"; + break; + case is80MHz: + ht_mode = "HT80"; + break; + case is160MHz: + ht_mode = "HT160"; + break; + case auto: + ht_mode = "0"; + break; + default: + ht_mode = null; + } + return ht_mode; + } + + String getHwMode(RfElementConfiguration rfElementConfig) { + String hwMode = null; + switch (rfElementConfig.getRadioMode()) { + case modeA: + hwMode = "11a"; + break; + case modeAB: + hwMode = "11ab"; + break; + case modeAC: + hwMode = "11ac"; + break; + case modeB: + hwMode = "11b"; + break; + case modeG: + hwMode = "11g"; + break; + case modeAX: + hwMode = "11ax"; + break; + case modeN: + hwMode = "11n"; + break; + default: + } + return hwMode; + } + void configureWifiRadios(String freqBand, int channel, Map hwConfig, String country, int beaconInterval, boolean enabled, String hwMode, String ht_mode, int txPower, - int mimoMode, Set vifUuidsForRadio, List operations) throws OvsdbClientException, TimeoutException, ExecutionException, InterruptedException { - + int mimoMode, Set vifUuidsForRadio, List operations, int maxNumClients) throws OvsdbClientException, TimeoutException, ExecutionException, InterruptedException { Map updateColumns = new HashMap<>(); List conditions = new ArrayList<>(); conditions.add(new Condition("freq_band", Function.EQUALS, new Atom<>(freqBand))); - updateColumns.put("channel", new Atom<>(channel)); updateColumns.put("country", new Atom<>(country)); @SuppressWarnings("unchecked") @@ -260,18 +242,24 @@ public class OvsdbRadioConfig extends OvsdbDaoBase { if (hwMode != null) { updateColumns.put("hw_mode", new Atom<>(hwMode)); } - + configureCustomOptionsMap(maxNumClients, updateColumns); setTxAndRxChainmask(mimoMode, updateColumns); - if (vifUuidsForRadio.size() > 0) { com.vmware.ovsdb.protocol.operation.notation.Set vifConfigUuids = com.vmware.ovsdb.protocol.operation.notation.Set .of(vifUuidsForRadio); updateColumns.put("vif_configs", vifConfigUuids); } - Row row = new Row(updateColumns); operations.add(new Update(wifiRadioConfigDbTable, conditions, row)); + } + void configureCustomOptionsMap(int maxNumClients, Map updateColumns) { + Map customOptions = new HashMap<>(); + customOptions.put("max_clients", String.valueOf(maxNumClients)); + @SuppressWarnings("unchecked") + com.vmware.ovsdb.protocol.operation.notation.Map customOptionsMap = com.vmware.ovsdb.protocol.operation.notation.Map + .of(customOptions); + updateColumns.put("custom_options", customOptionsMap); } void setTxAndRxChainmask(int mimoMode, Map updateColumns) { @@ -290,8 +278,7 @@ public class OvsdbRadioConfig extends OvsdbDaoBase { else if (mimoMode == 3) {mimoMode = 7;} else if (mimoMode == 4) {mimoMode = 15;} updateColumns.put("tx_chainmask", new Atom<>(mimoMode)); - updateColumns.put("rx_chainmask", new Atom<>(mimoMode)); - + updateColumns.put("rx_chainmask", new Atom<>(mimoMode)); } } diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/metrics/OvsdbClientWithMetrics.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/metrics/OvsdbClientWithMetrics.java new file mode 100644 index 0000000..8427723 --- /dev/null +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/metrics/OvsdbClientWithMetrics.java @@ -0,0 +1,78 @@ +package com.telecominfraproject.wlan.opensync.ovsdb.metrics; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import com.vmware.ovsdb.callback.LockCallback; +import com.vmware.ovsdb.callback.MonitorCallback; +import com.vmware.ovsdb.exception.OvsdbClientException; +import com.vmware.ovsdb.protocol.methods.LockResult; +import com.vmware.ovsdb.protocol.methods.MonitorRequests; +import com.vmware.ovsdb.protocol.methods.TableUpdates; +import com.vmware.ovsdb.protocol.operation.Operation; +import com.vmware.ovsdb.protocol.operation.result.OperationResult; +import com.vmware.ovsdb.protocol.schema.DatabaseSchema; +import com.vmware.ovsdb.service.OvsdbClient; +import com.vmware.ovsdb.service.OvsdbConnectionInfo; + +public class OvsdbClientWithMetrics implements OvsdbClient { + + private final OvsdbMetrics metrics; + private final OvsdbClient delegate; + + public OvsdbClientWithMetrics(OvsdbClient delegate, OvsdbMetrics metrics) { + this.delegate = delegate; + this.metrics = metrics; + } + + public CompletableFuture listDatabases() throws OvsdbClientException { + metrics.listDatabases.increment(); + return delegate.listDatabases(); + } + + public CompletableFuture getSchema(String dbName) throws OvsdbClientException { + metrics.getSchema.increment(); + return delegate.getSchema(dbName); + } + + public CompletableFuture transact(String dbName, List operations) + throws OvsdbClientException { + metrics.transact.increment(); + return delegate.transact(dbName, operations); + } + + public CompletableFuture monitor(String dbName, String monitorId, MonitorRequests monitorRequests, + MonitorCallback monitorCallback) throws OvsdbClientException { + metrics.monitor.increment(); + return delegate.monitor(dbName, monitorId, monitorRequests, monitorCallback); + } + + public CompletableFuture cancelMonitor(String monitorId) throws OvsdbClientException { + metrics.cancelMonitor.increment(); + return delegate.cancelMonitor(monitorId); + } + + public CompletableFuture lock(String lockId, LockCallback lockCallback) throws OvsdbClientException { + metrics.lock.increment(); + return delegate.lock(lockId, lockCallback); + } + + public CompletableFuture steal(String lockId, LockCallback lockCallback) throws OvsdbClientException { + metrics.steal.increment(); + return delegate.steal(lockId, lockCallback); + } + + public CompletableFuture unlock(String lockId) throws OvsdbClientException { + metrics.unlock.increment(); + return delegate.unlock(lockId); + } + + public OvsdbConnectionInfo getConnectionInfo() { + return delegate.getConnectionInfo(); + } + + public void shutdown() { + delegate.shutdown(); + } + +} diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/metrics/OvsdbMetrics.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/metrics/OvsdbMetrics.java new file mode 100644 index 0000000..4700cdc --- /dev/null +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/metrics/OvsdbMetrics.java @@ -0,0 +1,40 @@ +package com.telecominfraproject.wlan.opensync.ovsdb.metrics; + +import org.springframework.stereotype.Component; + +import com.netflix.servo.DefaultMonitorRegistry; +import com.netflix.servo.monitor.BasicCounter; +import com.netflix.servo.monitor.Counter; +import com.netflix.servo.monitor.MonitorConfig; +import com.netflix.servo.tag.TagList; +import com.telecominfraproject.wlan.cloudmetrics.CloudMetricsTags; + +@Component +public class OvsdbMetrics { + + private final TagList tags = CloudMetricsTags.commonTags; + + final Counter listDatabases = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-listDatabases").withTags(tags).build()); + final Counter getSchema = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-getSchema").withTags(tags).build()); + final Counter transact = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-transact").withTags(tags).build()); + final Counter monitor = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-monitor").withTags(tags).build()); + final Counter cancelMonitor = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-cancelMonitor").withTags(tags).build()); + final Counter lock = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-lock").withTags(tags).build()); + final Counter steal = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-steal").withTags(tags).build()); + final Counter unlock = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-unlock").withTags(tags).build()); + + // dtop: use anonymous constructor to ensure that the following code always + // get executed, + // even when somebody adds another constructor in here + { + DefaultMonitorRegistry.getInstance().register(listDatabases); + DefaultMonitorRegistry.getInstance().register(getSchema); + DefaultMonitorRegistry.getInstance().register(transact); + DefaultMonitorRegistry.getInstance().register(monitor); + DefaultMonitorRegistry.getInstance().register(cancelMonitor); + DefaultMonitorRegistry.getInstance().register(lock); + DefaultMonitorRegistry.getInstance().register(steal); + DefaultMonitorRegistry.getInstance().register(unlock); + } + +} diff --git a/opensync-gateway/src/test/java/com/telecominfraproject/wlan/opensync/ovsdb/OpensyncGatewayTipWlanOvsdbClientTest.java b/opensync-gateway/src/test/java/com/telecominfraproject/wlan/opensync/ovsdb/OpensyncGatewayTipWlanOvsdbClientTest.java index 4ad1705..cd9afce 100644 --- a/opensync-gateway/src/test/java/com/telecominfraproject/wlan/opensync/ovsdb/OpensyncGatewayTipWlanOvsdbClientTest.java +++ b/opensync-gateway/src/test/java/com/telecominfraproject/wlan/opensync/ovsdb/OpensyncGatewayTipWlanOvsdbClientTest.java @@ -30,6 +30,7 @@ import com.telecominfraproject.wlan.opensync.external.integration.OvsdbSession; import com.telecominfraproject.wlan.opensync.external.integration.OvsdbSessionMapInterface; import com.telecominfraproject.wlan.opensync.external.integration.models.OpensyncAPConfig; import com.telecominfraproject.wlan.opensync.ovsdb.dao.OvsdbDao; +import com.telecominfraproject.wlan.opensync.ovsdb.metrics.OvsdbMetrics; import com.telecominfraproject.wlan.profile.network.models.ApNetworkConfiguration; import com.vmware.ovsdb.callback.MonitorCallback; import com.vmware.ovsdb.exception.OvsdbClientException; @@ -47,7 +48,7 @@ import io.netty.handler.ssl.SslContext; @SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = OpensyncGatewayTipWlanOvsdbClientTest.class) @Import(value = { OpensyncGatewayTipWlanOvsdbClientTest.Config.class, TipWlanOvsdbClient.class, TipWlanOvsdbRedirector.class, OvsdbListenerConfig.class, OvsdbSessionMapInterface.class, OvsdbDao.class, - OpensyncExternalIntegrationInterface.class, OvsdbSession.class, SslContext.class }) + OpensyncExternalIntegrationInterface.class, OvsdbSession.class, OvsdbMetrics.class, SslContext.class }) public class OpensyncGatewayTipWlanOvsdbClientTest { @MockBean