WIFI-1669: propagations

This commit is contained in:
Akshay Jagadish
2021-03-09 16:58:41 -05:00
parent 35108f0a5d
commit bad137c0b3
10 changed files with 455 additions and 137 deletions

View File

@@ -877,7 +877,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
LOG.info("OpensyncExternalIntegrationCloud::disconnectClients for Equipment {}", ce);
PaginationResponse<ClientSession> 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<ClientSession>(100));
if (clientSessions == null) {
@@ -1859,7 +1859,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
List<ClientSession> clientSessionsForCustomerAndEquipment = new ArrayList<>();
if (ce != null) {
PaginationResponse<ClientSession> clientSessions = clientServiceInterface.getSessionsForCustomer(customerId,
ImmutableSet.of(equipmentId), ImmutableSet.of(ce.getLocationId()), null,
ImmutableSet.of(equipmentId), ImmutableSet.of(ce.getLocationId()), null, null,
new PaginationContext<ClientSession>());
clientSessionsForCustomerAndEquipment.addAll(clientSessions.getItems());
}

View File

@@ -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<ContextClosedEven
public static Charset utf8 = Charset.forName("UTF-8");
private final TagList tags = CloudMetricsTags.commonTags;
private final Counter messagesReceived = new BasicCounter(
MonitorConfig.builder("osgw-mqtt-messagesReceived").withTags(tags).build());
private final Counter messageBytesReceived = new BasicCounter(
MonitorConfig.builder("osgw-mqtt-messageBytesReceived").withTags(tags).build());
private final Timer timerMessageProcess = new BasicTimer(
MonitorConfig.builder("osgw-mqtt-messageProcessTimer").withTags(tags).build());
@Autowired
private OpensyncExternalIntegrationInterface extIntegrationInterface;
// dtop: use anonymous constructor to ensure that the following code always
// get executed,
// even when somebody adds another constructor in here
{
DefaultMonitorRegistry.getInstance().register(messagesReceived);
DefaultMonitorRegistry.getInstance().register(messageBytesReceived);
DefaultMonitorRegistry.getInstance().register(timerMessageProcess);
}
//
// See https://github.com/fusesource/mqtt-client for the docs
//
@@ -180,6 +210,10 @@ public class OpensyncMqttClient implements ApplicationListener<ContextClosedEven
// queue
mqttMsg.ack();
messagesReceived.increment();
messageBytesReceived.increment(payload.length);
Stopwatch stopwatchTimerMessageProcess = timerMessageProcess.start();
LOG.trace("received message on topic {} size {}", mqttMsg.getTopic(), payload.length);
if (payload[0] == 0x78) {
@@ -189,6 +223,7 @@ public class OpensyncMqttClient implements ApplicationListener<ContextClosedEven
payload = ZlibUtil.decompress(payload);
}
// attempt to parse the message as protobuf
MessageOrBuilder encodedMsg = null;
try {
@@ -198,7 +233,6 @@ public class OpensyncMqttClient implements ApplicationListener<ContextClosedEven
MQTT_LOG.info("topic = {} Report = {}", mqttMsg.getTopic(),
jsonPrinter.print(encodedMsg));
extIntegrationInterface.processMqttMessage(mqttMsg.getTopic(), (Report) encodedMsg);
} catch (Exception e) {
@@ -231,6 +265,8 @@ public class OpensyncMqttClient implements ApplicationListener<ContextClosedEven
MQTT_LOG.info("topic = {} message = {}", mqttMsg.getTopic(), msgStr);
}
}
} finally {
stopwatchTimerMessageProcess.stop();
}
}

View File

@@ -1,13 +1,24 @@
package com.telecominfraproject.wlan.opensync.ovsdb;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.NumberGauge;
import com.netflix.servo.tag.TagList;
import com.telecominfraproject.wlan.cloudmetrics.CloudMetricsTags;
import com.vmware.ovsdb.service.OvsdbPassiveConnectionListener;
import com.vmware.ovsdb.service.impl.OvsdbPassiveConnectionListenerImpl;
@@ -16,12 +27,68 @@ public class OvsdbListenerConfig {
private static final Logger LOG = LoggerFactory.getLogger(OvsdbListenerConfig.class);
private final TagList tags = CloudMetricsTags.commonTags;
final Counter rejectedTasks = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-rejectedTasks").withTags(tags).build());
final Counter submittedTasks = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-submittedTasks").withTags(tags).build());
final Counter completedTasks = new BasicCounter(MonitorConfig.builder("osgw-ovsdb-completedTasks").withTags(tags).build());
private AtomicInteger tasksInFlight = new AtomicInteger(0);
private final NumberGauge tasksInFlightGauge = new NumberGauge(
MonitorConfig.builder("osgw-ovsdb-tasksInFlight").withTags(tags).build(), tasksInFlight);
// dtop: use anonymous constructor to ensure that the following code always
// get executed,
// even when somebody adds another constructor in here
{
DefaultMonitorRegistry.getInstance().register(rejectedTasks);
DefaultMonitorRegistry.getInstance().register(submittedTasks);
DefaultMonitorRegistry.getInstance().register(completedTasks);
DefaultMonitorRegistry.getInstance().register(tasksInFlightGauge);
}
@Bean
public OvsdbPassiveConnectionListener ovsdbPassiveConnectionListener(
@org.springframework.beans.factory.annotation.Value("${tip.wlan.ovsdb.listener.threadPoolSize:10}")
int threadPoolSize) {
LOG.debug("Configuring OvsdbPassiveConnectionListener with thread pool size {}", threadPoolSize);
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(threadPoolSize);
ThreadFactory threadFactory = new ThreadFactory() {
private AtomicInteger thrNum = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
Thread thr = new Thread(r, "ovsdb-exec-pool-" + thrNum.incrementAndGet());
thr.setDaemon(true);
return thr;
}
};
RejectedExecutionHandler rejectedExecHandler = new ThreadPoolExecutor.AbortPolicy() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
rejectedTasks.increment();
super.rejectedExecution(r, executor);
}
};
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(threadPoolSize, threadFactory, rejectedExecHandler) {
@Override
protected void beforeExecute(Thread t, Runnable r) {
submittedTasks.increment();
tasksInFlight.incrementAndGet();
super.beforeExecute(t, r);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
completedTasks.increment();
tasksInFlight.decrementAndGet();
super.afterExecute(r, t);
}
};
OvsdbPassiveConnectionListener listener = new OvsdbPassiveConnectionListenerImpl(executorService);
return listener;
}

View File

@@ -1,14 +1,21 @@
package com.telecominfraproject.wlan.opensync.ovsdb;
import java.util.HashSet;
import java.util.Set;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.netflix.servo.DefaultMonitorRegistry;
import com.netflix.servo.monitor.MonitorConfig;
import com.netflix.servo.monitor.Monitors;
import com.netflix.servo.monitor.NumberGauge;
import com.netflix.servo.tag.TagList;
import com.telecominfraproject.wlan.cloudmetrics.CloudMetricsTags;
import com.telecominfraproject.wlan.opensync.external.integration.OvsdbSession;
import com.telecominfraproject.wlan.opensync.external.integration.OvsdbSessionMapInterface;
import com.vmware.ovsdb.service.OvsdbClient;
@@ -17,9 +24,23 @@ import com.vmware.ovsdb.service.OvsdbClient;
public class OvsdbSessionMap implements OvsdbSessionMapInterface {
private static final Logger LOG = LoggerFactory.getLogger(OvsdbSessionMap.class);
private final TagList tags = CloudMetricsTags.commonTags;
private AtomicInteger totalEquipmentConnections = new AtomicInteger(0);
private final NumberGauge totalEquipmentConnectionsGauge = new NumberGauge(
MonitorConfig.builder("osgw-totalEquipmentConnections").withTags(tags).build(), totalEquipmentConnections);
private final ConcurrentHashMap<String, OvsdbSession> 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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<String, WifiRadioConfigInfo> provisionedRadioConfigs = ovsdbGet.getProvisionedWifiRadioConfigs(ovsdbClient);
Map<String, WifiVifConfigInfo> vifConfigs = ovsdbGet.getProvisionedWifiVifConfigs(ovsdbClient);
List<Operation> operations = new ArrayList<>();
for (RadioType radioType : apElementConfiguration.getRadioMap().keySet()) {
Map<String, String> 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<Uuid> 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<OperationResult[]> 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<String, String> 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<String, String> hwConfig,
String country, int beaconInterval, boolean enabled, String hwMode, String ht_mode, int txPower,
int mimoMode, Set<Uuid> vifUuidsForRadio, List<Operation> operations) throws OvsdbClientException, TimeoutException, ExecutionException, InterruptedException {
int mimoMode, Set<Uuid> vifUuidsForRadio, List<Operation> operations, int maxNumClients) throws OvsdbClientException, TimeoutException, ExecutionException, InterruptedException {
Map<String, Value> updateColumns = new HashMap<>();
List<Condition> 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<String, Value> updateColumns) {
Map<String,String> customOptions = new HashMap<>();
customOptions.put("max_clients", String.valueOf(maxNumClients));
@SuppressWarnings("unchecked")
com.vmware.ovsdb.protocol.operation.notation.Map<String, String> customOptionsMap = com.vmware.ovsdb.protocol.operation.notation.Map
.of(customOptions);
updateColumns.put("custom_options", customOptionsMap);
}
void setTxAndRxChainmask(int mimoMode, Map<String, Value> 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));
}
}

View File

@@ -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<String[]> listDatabases() throws OvsdbClientException {
metrics.listDatabases.increment();
return delegate.listDatabases();
}
public CompletableFuture<DatabaseSchema> getSchema(String dbName) throws OvsdbClientException {
metrics.getSchema.increment();
return delegate.getSchema(dbName);
}
public CompletableFuture<OperationResult[]> transact(String dbName, List<Operation> operations)
throws OvsdbClientException {
metrics.transact.increment();
return delegate.transact(dbName, operations);
}
public CompletableFuture<TableUpdates> monitor(String dbName, String monitorId, MonitorRequests monitorRequests,
MonitorCallback monitorCallback) throws OvsdbClientException {
metrics.monitor.increment();
return delegate.monitor(dbName, monitorId, monitorRequests, monitorCallback);
}
public CompletableFuture<Void> cancelMonitor(String monitorId) throws OvsdbClientException {
metrics.cancelMonitor.increment();
return delegate.cancelMonitor(monitorId);
}
public CompletableFuture<LockResult> lock(String lockId, LockCallback lockCallback) throws OvsdbClientException {
metrics.lock.increment();
return delegate.lock(lockId, lockCallback);
}
public CompletableFuture<LockResult> steal(String lockId, LockCallback lockCallback) throws OvsdbClientException {
metrics.steal.increment();
return delegate.steal(lockId, lockCallback);
}
public CompletableFuture<Void> unlock(String lockId) throws OvsdbClientException {
metrics.unlock.increment();
return delegate.unlock(lockId);
}
public OvsdbConnectionInfo getConnectionInfo() {
return delegate.getConnectionInfo();
}
public void shutdown() {
delegate.shutdown();
}
}

View File

@@ -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);
}
}

View File

@@ -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