Retrieve Radio State information on initial AP connect

This commit is contained in:
Mike Hansen
2020-06-23 17:46:31 -04:00
parent 2be3559547
commit 82332611ce
6 changed files with 911 additions and 772 deletions

View File

@@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.function.Consumer;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
@@ -39,7 +40,6 @@ import com.telecominfraproject.wlan.core.model.equipment.RadioType;
import com.telecominfraproject.wlan.customer.models.Customer; import com.telecominfraproject.wlan.customer.models.Customer;
import com.telecominfraproject.wlan.customer.service.CustomerServiceInterface; import com.telecominfraproject.wlan.customer.service.CustomerServiceInterface;
import com.telecominfraproject.wlan.datastore.exceptions.DsConcurrentModificationException; import com.telecominfraproject.wlan.datastore.exceptions.DsConcurrentModificationException;
import com.telecominfraproject.wlan.datastore.exceptions.DsEntityNotFoundException;
import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface; import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface;
import com.telecominfraproject.wlan.equipment.models.ApElementConfiguration; import com.telecominfraproject.wlan.equipment.models.ApElementConfiguration;
import com.telecominfraproject.wlan.equipment.models.Equipment; import com.telecominfraproject.wlan.equipment.models.Equipment;
@@ -48,7 +48,6 @@ import com.telecominfraproject.wlan.firmware.FirmwareServiceInterface;
import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackRecord; import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackRecord;
import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackSettings; import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackSettings;
import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackSettings.TrackFlag; import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackSettings.TrackFlag;
import com.telecominfraproject.wlan.firmware.models.FirmwareVersion;
import com.telecominfraproject.wlan.location.models.Location; import com.telecominfraproject.wlan.location.models.Location;
import com.telecominfraproject.wlan.location.service.LocationServiceInterface; import com.telecominfraproject.wlan.location.service.LocationServiceInterface;
import com.telecominfraproject.wlan.opensync.external.integration.controller.OpensyncCloudGatewayController; import com.telecominfraproject.wlan.opensync.external.integration.controller.OpensyncCloudGatewayController;
@@ -115,10 +114,6 @@ import sts.OpensyncStats.Neighbor;
import sts.OpensyncStats.Neighbor.NeighborBss; import sts.OpensyncStats.Neighbor.NeighborBss;
import sts.OpensyncStats.RadioBandType; import sts.OpensyncStats.RadioBandType;
import sts.OpensyncStats.Report; import sts.OpensyncStats.Report;
import sts.OpensyncStats.RssiPeer;
import sts.OpensyncStats.RssiPeer.RssiSample;
import sts.OpensyncStats.RssiPeer.RssiSource;
import sts.OpensyncStats.RssiReport;
import sts.OpensyncStats.Survey; import sts.OpensyncStats.Survey;
import sts.OpensyncStats.Survey.SurveySample; import sts.OpensyncStats.Survey.SurveySample;
import sts.OpensyncStats.SurveyType; import sts.OpensyncStats.SurveyType;
@@ -129,7 +124,7 @@ import wc.stats.IpDnsTelemetry.WCStatsReport;
@Component @Component
public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegrationInterface { public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegrationInterface {
private static final Logger LOG = LoggerFactory.getLogger(OpensyncExternalIntegrationCloud.class); private static Logger LOG = LoggerFactory.getLogger(OpensyncExternalIntegrationCloud.class);
@Autowired @Autowired
private AlarmServiceInterface alarmServiceInterface; private AlarmServiceInterface alarmServiceInterface;
@@ -197,6 +192,41 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
return ce; return ce;
} }
private RadioType opensyncFreqBandToRadioType(String osFreqBand) {
switch (osFreqBand) {
case "2.4G":
return RadioType.is2dot4GHz;
case "5G":
return RadioType.is5GHz;
case "5GL":
return RadioType.is5GHzL;
case "5GU":
return RadioType.is5GHzU;
default:
return RadioType.UNSUPPORTED;
}
}
private String radioTypeToOpensyncFrequencyBand(RadioType radioType) {
switch (radioType) {
case is2dot4GHz:
return "2.4G";
case is5GHz:
return "5G";
case is5GHzL:
return "5GL";
case is5GHzU:
return "5GU";
default:
return null;
}
}
@Override @Override
public void apConnected(String apId, ConnectNodeInfo connectNodeInfo) { public void apConnected(String apId, ConnectNodeInfo connectNodeInfo) {
@@ -208,9 +238,10 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
CustomerFirmwareTrackRecord custFwTrackRecord = firmwareServiceInterface CustomerFirmwareTrackRecord custFwTrackRecord = firmwareServiceInterface
.getCustomerFirmwareTrackRecord(autoProvisionedCustomerId); .getCustomerFirmwareTrackRecord(autoProvisionedCustomerId);
if (custFwTrackRecord != null) { if (custFwTrackRecord != null) {
trackSettings = custFwTrackRecord.getSettings(); trackSettings = CustomerFirmwareTrackSettings.combine(custFwTrackRecord.getSettings(), trackSettings);
} }
// determine if AP requires FW upgrade before cloud connection/provision // determine if AP requires FW upgrade before cloud
// connection/provision
if (trackSettings.getAutoUpgradeDeprecatedOnBind().equals(TrackFlag.ALWAYS) if (trackSettings.getAutoUpgradeDeprecatedOnBind().equals(TrackFlag.ALWAYS)
|| trackSettings.getAutoUpgradeUnknownOnBind().equals(TrackFlag.ALWAYS)) { || trackSettings.getAutoUpgradeUnknownOnBind().equals(TrackFlag.ALWAYS)) {
@@ -232,90 +263,69 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
try { try {
if (ce == null) { if (ce == null) {
Customer customer = customerServiceInterface.getOrNull(autoProvisionedCustomerId);
if (customer == null) {
customer = new Customer();
customer.setName("DefaultCustomer");
customer.setEmail("DefaulCustomer@DefaultEmail.com");
customer = customerServiceInterface.create(customer);
}
ce = new Equipment(); ce = new Equipment();
ce.setEquipmentType(EquipmentType.AP); ce.setEquipmentType(EquipmentType.AP);
ce.setCustomerId(customer.getId());
ce.setInventoryId(apId); ce.setInventoryId(apId);
ce.setSerial(connectNodeInfo.serialNumber); ce.setSerial(connectNodeInfo.serialNumber);
ce.setDetails(ApElementConfiguration.createWithDefaults()); ce.setDetails(ApElementConfiguration.createWithDefaults());
ce.setName(apId);
ce.setLocationId(autoProvisionedLocationId);
ce = equipmentServiceInterface.create(ce); ce = equipmentServiceInterface.create(ce);
ce.setCustomerId(autoProvisionedCustomerId); ce.setCustomerId(autoProvisionedCustomerId);
ce.setName(apId);
ce.setLocationId(autoProvisionedLocationId);
ApElementConfiguration apElementConfig = (ApElementConfiguration) ce.getDetails(); ApElementConfiguration apElementConfig = (ApElementConfiguration) ce.getDetails();
apElementConfig.setEquipmentModel(connectNodeInfo.model); for (RadioType key : apElementConfig.getRadioMap().keySet()) {
apElementConfig.getAdvancedRadioMap().get(RadioType.is2dot4GHz) String ovsdbKey = radioTypeToOpensyncFrequencyBand(key);
.setAutoChannelSelection(StateSetting.disabled); if (connectNodeInfo.wifiRadioStates.containsKey(ovsdbKey)) {
apElementConfig.getAdvancedRadioMap().get(RadioType.is5GHzL) apElementConfig.getAdvancedRadioMap().get(key)
.setAutoChannelSelection(StateSetting.disabled); .setAutoChannelSelection(StateSetting.disabled);
apElementConfig.getAdvancedRadioMap().get(RadioType.is5GHzU) apElementConfig.getRadioMap().get(key).setAutoChannelSelection(false);
.setAutoChannelSelection(StateSetting.disabled); } else {
apElementConfig.getAdvancedRadioMap().remove(key);
apElementConfig.getRadioMap().get(RadioType.is2dot4GHz).setAutoChannelSelection(false); apElementConfig.getRadioMap().remove(key);
apElementConfig.getRadioMap().get(RadioType.is5GHzL).setAutoChannelSelection(false); }
apElementConfig.getRadioMap().get(RadioType.is5GHzU).setAutoChannelSelection(false); }
ce.setDetails(apElementConfig); ce.setDetails(apElementConfig);
ce = equipmentServiceInterface.update(ce); ce = equipmentServiceInterface.update(ce);
Profile ssidProfile = new Profile();
ssidProfile.setCustomerId(ce.getCustomerId());
ssidProfile.setName("DefaultSsidApConnected");
SsidConfiguration ssidConfig = SsidConfiguration.createWithDefaults();
ssidConfig.setSsid("DefaultSsidApConnected");
ssidConfig.setSecureMode(SecureMode.wpa2PSK);
ssidConfig.setKeyStr("12345678");
Set<RadioType> appliedRadios = new HashSet<>();
appliedRadios.addAll(((ApElementConfiguration) ce.getDetails()).getRadioMap().keySet());
ssidConfig.setAppliedRadios(appliedRadios);
ssidProfile.setDetails(ssidConfig);
ssidProfile = profileServiceInterface.create(ssidProfile);
Profile apProfile = new Profile(); Profile apProfile = new Profile();
apProfile.setCustomerId(ce.getCustomerId()); apProfile.setCustomerId(ce.getCustomerId());
apProfile.setName("DefaultApProfile"); apProfile.setName("DefaultApProfile");
apProfile.setDetails(ApNetworkConfiguration.createWithDefaults()); apProfile.setDetails(ApNetworkConfiguration.createWithDefaults());
apProfile = profileServiceInterface.create(apProfile);
Profile ssidProfile = new Profile();
ssidProfile.setCustomerId(ce.getCustomerId());
ssidProfile.setName("DefaultSsid-2g");
SsidConfiguration ssidConfig = SsidConfiguration.createWithDefaults();
ssidConfig.setSsid("DefaultSsid-2g");
ssidConfig.setSecureMode(SecureMode.wpa2PSK);
ssidConfig.setKeyStr("12345678");
Set<RadioType> appliedRadios = new HashSet<>();
appliedRadios.add(RadioType.is2dot4GHz);
// ssidConfig.getRadioBasedConfigs().get(RadioType.is2dot4GHz).setEnable80211r(true);
ssidConfig.setAppliedRadios(appliedRadios);
ssidProfile.setDetails(ssidConfig);
ssidProfile = profileServiceInterface.create(ssidProfile);
Profile ssidProfile5g = new Profile();
ssidProfile5g.setCustomerId(ce.getCustomerId());
ssidProfile5g.setName("DefaultSsid-5g");
SsidConfiguration ssidConfig5g = SsidConfiguration.createWithDefaults();
ssidConfig5g.setSecureMode(SecureMode.wpa2PSK);
ssidConfig5g.setSsid("DefaultSsid-5g");
ssidConfig5g.setKeyStr("12345678");
Set<RadioType> appliedRadios5g = new HashSet<>();
appliedRadios5g.add(RadioType.is5GHzL);
appliedRadios5g.add(RadioType.is5GHzU);
ssidConfig5g.setAppliedRadios(appliedRadios5g);
// ssidConfig5g.getRadioBasedConfigs().get(RadioType.is5GHzL).setEnable80211r(true);
// ssidConfig5g.getRadioBasedConfigs().get(RadioType.is5GHzU).setEnable80211r(true);
ssidProfile5g.setDetails(ssidConfig5g);
ssidProfile5g = profileServiceInterface.create(ssidProfile5g);
Set<Long> childProfileIds = new HashSet<>(); Set<Long> childProfileIds = new HashSet<>();
childProfileIds.add(ssidProfile.getId()); childProfileIds.add(ssidProfile.getId());
childProfileIds.add(ssidProfile5g.getId());
apProfile.setChildProfileIds(childProfileIds); apProfile.setChildProfileIds(childProfileIds);
apProfile = profileServiceInterface.create(apProfile);
apProfile = profileServiceInterface.update(apProfile);
ce.setProfileId(apProfile.getId()); ce.setProfileId(apProfile.getId());
ce = equipmentServiceInterface.update(ce); ce = equipmentServiceInterface.update(ce);
Customer customer = customerServiceInterface.getOrNull(ce.getCustomerId());
if (customer == null) {
customer = new Customer();
customer.setId(autoProvisionedCustomerId);
customerServiceInterface.create(customer);
ce.setCustomerId(customer.getId());
equipmentServiceInterface.update(ce);
}
} }
EquipmentRoutingRecord equipmentRoutingRecord = gatewayController EquipmentRoutingRecord equipmentRoutingRecord = gatewayController
@@ -405,7 +415,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
// do nothing here // do nothing here
} }
if (connectNodeInfo.macAddress != null && MacAddress.valueOf(connectNodeInfo.macAddress) != null) { if ((connectNodeInfo.macAddress != null) && (MacAddress.valueOf(connectNodeInfo.macAddress) != null)) {
protocolStatusData.setReportedMacAddr(MacAddress.valueOf(connectNodeInfo.macAddress)); protocolStatusData.setReportedMacAddr(MacAddress.valueOf(connectNodeInfo.macAddress));
} }
protocolStatusData.setReportedSku(connectNodeInfo.skuNumber); protocolStatusData.setReportedSku(connectNodeInfo.skuNumber);
@@ -633,7 +643,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
int customerId = extractCustomerIdFromTopic(topic); int customerId = extractCustomerIdFromTopic(topic);
long equipmentId = extractEquipmentIdFromTopic(topic); long equipmentId = extractEquipmentIdFromTopic(topic);
if (equipmentId <= 0 || customerId <= 0) { if ((equipmentId <= 0) || (customerId <= 0)) {
LOG.warn("Cannot determine equipment ids from topic {} - customerId {} equipmentId {}", topic, customerId, LOG.warn("Cannot determine equipment ids from topic {} - customerId {} equipmentId {}", topic, customerId,
equipmentId); equipmentId);
return; return;
@@ -647,13 +657,12 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
populateApNodeMetrics(metricRecordList, report, customerId, equipmentId); populateApNodeMetrics(metricRecordList, report, customerId, equipmentId);
populateNeighbourScanReports(metricRecordList, report, customerId, equipmentId); populateNeighbourScanReports(metricRecordList, report, customerId, equipmentId);
try { try {
// TODO: depends on survey populateChannelInfoReports(metricRecordList, report, customerId, equipmentId);
// populateChannelInfoReports(metricRecordList, report, customerId,
// equipmentId);
populateApSsidMetrics(metricRecordList, report, customerId, equipmentId, extractApIdFromTopic(topic)); populateApSsidMetrics(metricRecordList, report, customerId, equipmentId, extractApIdFromTopic(topic));
// handleRssiMetrics(metricRecordList, report, customerId, /*
// equipmentId); * TODO: add when available handleRssiMetrics(metricRecordList,
* report, customerId, equipmentId);
*/
} catch (Exception e) { } catch (Exception e) {
LOG.error("Exception when processing populateApSsidMetrics", e); LOG.error("Exception when processing populateApSsidMetrics", e);
} }
@@ -664,31 +673,32 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
} }
private void handleRssiMetrics(List<ServiceMetric> metricRecordList, Report report, int customerId, /*
long equipmentId) { * TODO: when available handle RSSI metric processing private void
LOG.debug("handleRssiMetrics for Customer {} Equipment {}", customerId, equipmentId); * handleRssiMetrics(List<ServiceMetric> metricRecordList, Report report,
* int customerId, long equipmentId) {
for (RssiReport rssiReport : report.getRssiReportList()) { * LOG.debug("handleRssiMetrics for Customer {} Equipment {}", customerId,
* equipmentId);
for (RssiPeer peer : rssiReport.getPeerListList()) { *
if (peer.getRssiSource().equals(RssiSource.CLIENT)) { * for (RssiReport rssiReport : report.getRssiReportList()) {
int rssi = 0; *
* for (RssiPeer peer : rssiReport.getPeerListList()) { if
for (RssiSample sample : peer.getRssiListList()) { * (peer.getRssiSource().equals(RssiSource.CLIENT)) { int rssi = 0;
rssi += getNegativeSignedIntFromUnsigned(sample.getRssi()); *
LOG.debug("RSSI Sample: unsignedValue {} signedValue {}", sample.getRssi(), * for (RssiSample sample : peer.getRssiListList()) { rssi +=
getNegativeSignedIntFromUnsigned(sample.getRssi())); * getNegativeSignedIntFromUnsigned(sample.getRssi());
} * LOG.debug("RSSI Sample: unsignedValue {} signedValue {}",
* sample.getRssi(), getNegativeSignedIntFromUnsigned(sample.getRssi())); }
rssi = rssi / peer.getRssiListCount(); *
* rssi = rssi / peer.getRssiListCount();
LOG.debug("RssiReport::RssiPeer::Band {} RssiPeer MAC {} RssiSamples Avg {} RxPpdus {} TxPpdus {}", *
rssiReport.getBand(), peer.getMacAddress(), rssi, peer.getRxPpdus(), peer.getTxPpdus()); * LOG.
} * debug("RssiReport::RssiPeer::Band {} RssiPeer MAC {} RssiSamples Avg {} RxPpdus {} TxPpdus {}"
} * , rssiReport.getBand(), peer.getMacAddress(), rssi, peer.getRxPpdus(),
* peer.getTxPpdus()); } }
} *
} * } }
*/
private void populateApNodeMetrics(List<ServiceMetric> metricRecordList, Report report, int customerId, private void populateApNodeMetrics(List<ServiceMetric> metricRecordList, Report report, int customerId,
long equipmentId) { long equipmentId) {
@@ -890,7 +900,8 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
ClientMetrics cMetrics = new ClientMetrics(); ClientMetrics cMetrics = new ClientMetrics();
smr.setDetails(cMetrics); smr.setDetails(cMetrics);
Integer periodLengthSec = 60; // matches what's configured by Integer periodLengthSec = 60; // matches what's configured
// by
// OvsdbDao.configureStats(OvsdbClient) // OvsdbDao.configureStats(OvsdbClient)
cMetrics.setPeriodLengthSec(periodLengthSec); cMetrics.setPeriodLengthSec(periodLengthSec);
@@ -934,7 +945,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
} }
if (cl.getStats().hasTxRate()) { if (cl.getStats().hasTxRate()) {
cMetrics.setAverageTxRate(Double.valueOf(cl.getStats().getTxRate() / 1000)); cMetrics.setAverageTxRate(cl.getStats().getTxRate() / 1000);
} }
if (cl.getStats().hasTxRate() && cl.getStats().hasRxRate()) { if (cl.getStats().hasTxRate() && cl.getStats().hasRxRate()) {
@@ -1010,7 +1021,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
nr.setMacAddress(new MacAddress(nBss.getBssid())); nr.setMacAddress(new MacAddress(nBss.getBssid()));
nr.setNetworkType(NetworkType.AP); nr.setNetworkType(NetworkType.AP);
nr.setPacketType(NeighborScanPacketType.BEACON); nr.setPacketType(NeighborScanPacketType.BEACON);
nr.setPrivacy((nBss.getSsid() == null || nBss.getSsid().isEmpty()) ? true : false); nr.setPrivacy(((nBss.getSsid() == null) || nBss.getSsid().isEmpty()) ? true : false);
// nr.setRate(rate); // nr.setRate(rate);
// we can only get Rssi as an unsigned int from opensync, so // we can only get Rssi as an unsigned int from opensync, so
// some shifting // some shifting
@@ -1120,8 +1131,8 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
metricDetails.setTxDataFrames((int) ((int) client.getStats().getTxFrames() - client.getStats().getTxRetries())); metricDetails.setTxDataFrames((int) ((int) client.getStats().getTxFrames() - client.getStats().getTxRetries()));
metricDetails.setRxDataFrames((int) ((int) client.getStats().getRxFrames() - client.getStats().getRxRetries())); metricDetails.setRxDataFrames((int) ((int) client.getStats().getRxFrames() - client.getStats().getRxRetries()));
// values reported in Kbps, convert to Mbps // values reported in Kbps, convert to Mbps
metricDetails.setRxMbps(Float.valueOf((float) (client.getStats().getRxRate() / 1000))); metricDetails.setRxMbps((float) (client.getStats().getRxRate() / 1000));
metricDetails.setTxMbps(Float.valueOf((float) (client.getStats().getTxRate() / 1000))); metricDetails.setTxMbps((float) (client.getStats().getTxRate() / 1000));
metricDetails.setRxRateKbps((long) client.getStats().getRxRate()); metricDetails.setRxRateKbps((long) client.getStats().getRxRate());
metricDetails.setTxRateKbps((long) client.getStats().getTxRate()); metricDetails.setTxRateKbps((long) client.getStats().getTxRate());
return metricDetails; return metricDetails;
@@ -1187,7 +1198,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
for (Client client : clientReport.getClientListList()) { for (Client client : clientReport.getClientListList()) {
if (client.hasSsid() && client.getSsid() != null && !client.getSsid().equals("")) { if (client.hasSsid() && (client.getSsid() != null) && !client.getSsid().equals("")) {
ssid = client.getSsid(); ssid = client.getSsid();
} }
@@ -1319,15 +1330,18 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
// ChannelInfo entries per surveyed channel // ChannelInfo entries per surveyed channel
Map<Integer, List<SurveySample>> sampleByChannelMap = new HashMap<>(); Map<Integer, List<SurveySample>> sampleByChannelMap = new HashMap<>();
survey.getSurveyListList().stream().forEach(s -> { survey.getSurveyListList().stream().forEach(new Consumer<SurveySample>() {
List<SurveySample> surveySampleList; @Override
if (sampleByChannelMap.get(s.getChannel()) == null) { public void accept(SurveySample s) {
surveySampleList = new ArrayList<>(); List<SurveySample> surveySampleList;
} else { if (sampleByChannelMap.get(s.getChannel()) == null) {
surveySampleList = sampleByChannelMap.get(s.getChannel()); surveySampleList = new ArrayList<>();
} else {
surveySampleList = sampleByChannelMap.get(s.getChannel());
}
surveySampleList.add(s);
sampleByChannelMap.put(s.getChannel(), surveySampleList);
} }
surveySampleList.add(s);
sampleByChannelMap.put(s.getChannel(), surveySampleList);
}); });
for (List<SurveySample> surveySampleList : sampleByChannelMap.values()) { for (List<SurveySample> surveySampleList : sampleByChannelMap.values()) {
@@ -1383,9 +1397,9 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
channelInfo.setWifiUtilization(totalWifi); channelInfo.setWifiUtilization(totalWifi);
channelInfo.setBandwidth(((ApElementConfiguration) equipmentServiceInterface.get(equipmentId).getDetails()) channelInfo.setBandwidth(((ApElementConfiguration) equipmentServiceInterface.get(equipmentId).getDetails())
.getRadioMap().get(radioType).getChannelBandwidth()); .getRadioMap().get(radioType).getChannelBandwidth());
channelInfo.setNoiseFloor(Integer.valueOf(-84)); // TODO: when this channelInfo.setNoiseFloor(-84); // TODO: when this
// becomes available // becomes available
// add // add
return channelInfo; return channelInfo;
} }
@@ -1396,7 +1410,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
int customerId = extractCustomerIdFromTopic(topic); int customerId = extractCustomerIdFromTopic(topic);
long equipmentId = extractEquipmentIdFromTopic(topic); long equipmentId = extractEquipmentIdFromTopic(topic);
if (equipmentId <= 0 || customerId <= 0) { if ((equipmentId <= 0) || (customerId <= 0)) {
LOG.warn("Cannot determine equipment ids from topic {} - customerId {} equipmentId {}", topic, customerId, LOG.warn("Cannot determine equipment ids from topic {} - customerId {} equipmentId {}", topic, customerId,
equipmentId); equipmentId);
return; return;
@@ -1420,7 +1434,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
int customerId = extractCustomerIdFromTopic(topic); int customerId = extractCustomerIdFromTopic(topic);
long equipmentId = extractEquipmentIdFromTopic(topic); long equipmentId = extractEquipmentIdFromTopic(topic);
if (equipmentId <= 0 || customerId <= 0) { if ((equipmentId <= 0) || (customerId <= 0)) {
LOG.warn("Cannot determine equipment ids from topic {} - customerId {} equipmentId {}", topic, customerId, LOG.warn("Cannot determine equipment ids from topic {} - customerId {} equipmentId {}", topic, customerId,
equipmentId); equipmentId);
return; return;
@@ -1453,13 +1467,13 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
return; return;
} }
if (vifStateTables == null || vifStateTables.isEmpty() || apId == null) { if ((vifStateTables == null) || vifStateTables.isEmpty() || (apId == null)) {
return; return;
} }
for (OpensyncAPVIFState vifState : vifStateTables) { for (OpensyncAPVIFState vifState : vifStateTables) {
if (vifState.getMac() != null && vifState.getSsid() != null && vifState.getChannel() > 0) { if ((vifState.getMac() != null) && (vifState.getSsid() != null) && (vifState.getChannel() > 0)) {
String bssid = vifState.getMac(); String bssid = vifState.getMac();
String ssid = vifState.getSsid(); String ssid = vifState.getSsid();
@@ -1550,7 +1564,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
int customerId = ovsdbSession.getCustomerId(); int customerId = ovsdbSession.getCustomerId();
long equipmentId = ovsdbSession.getEquipmentId(); long equipmentId = ovsdbSession.getEquipmentId();
if (customerId < 0 || equipmentId < 0) { if ((customerId < 0) || (equipmentId < 0)) {
LOG.debug("wifiRadioStatusDbTableUpdate::Cannot get valid CustomerId {} or EquipmentId {} for AP {}", LOG.debug("wifiRadioStatusDbTableUpdate::Cannot get valid CustomerId {} or EquipmentId {} for AP {}",
customerId, equipmentId, apId); customerId, equipmentId, apId);
return; return;
@@ -1704,14 +1718,10 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
return; return;
} }
if (inetStateTables == null || inetStateTables.isEmpty() || apId == null) { if ((inetStateTables == null) || inetStateTables.isEmpty() || (apId == null)) {
return; return;
} }
for (OpensyncAPInetState inetState : inetStateTables) {
// TODO: implement me
}
} }
@Override @Override
@@ -1738,7 +1748,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
return; return;
} }
if (wifiAssociatedClients == null || wifiAssociatedClients.isEmpty() || apId == null) { if ((wifiAssociatedClients == null) || wifiAssociatedClients.isEmpty() || (apId == null)) {
return; return;
} }
@@ -1757,7 +1767,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
int customerId = ovsdbSession.getCustomerId(); int customerId = ovsdbSession.getCustomerId();
long equipmentId = ovsdbSession.getEquipmentId(); long equipmentId = ovsdbSession.getEquipmentId();
if (customerId < 0 || equipmentId < 0) { if ((customerId < 0) || (equipmentId < 0)) {
LOG.debug("awlanNodeDbTableUpdate::Cannot get valid CustomerId {} or EquipmentId {} for AP {}", customerId, LOG.debug("awlanNodeDbTableUpdate::Cannot get valid CustomerId {} or EquipmentId {} for AP {}", customerId,
equipmentId, apId); equipmentId, apId);
return; return;

View File

@@ -10,6 +10,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Consumer;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -122,62 +123,66 @@ public class OpensyncCloudGatewayController {
return ret; return ret;
} }
commands.stream().forEach(command -> { commands.stream().forEach(new Consumer<CEGWBaseCommand>() {
LOG.debug("sendCommands - processing {}", command); @Override
public void accept(CEGWBaseCommand command) {
LOG.debug("sendCommands - processing {}", command);
String inventoryId = command.getInventoryId(); String inventoryId = command.getInventoryId();
if (com.telecominfraproject.wlan.core.model.json.BaseJsonModel.hasUnsupportedValue(command)) {
LOG.error("[{}] Failed to deliver command {}, command contains unsupported value", inventoryId,
command);
ret.add(new EquipmentCommandResponse(CEGWCommandResultCode.UnsupportedCommand,
"Unsupported value in command for " + inventoryId, command, registeredGateway.getHostname(),
registeredGateway.getPort()));
return;
}
OvsdbSession session = ovsdbSessionMapInterface.getSession(inventoryId);
if (session == null) {
LOG.warn("[{}] Failed to deliver command {}, equipment session not found", inventoryId, command);
ret.add(new EquipmentCommandResponse(CEGWCommandResultCode.NoRouteToCE,
"No session found for " + inventoryId, command, registeredGateway.getHostname(),
registeredGateway.getPort()));
return;
}
switch (command.getCommandType()) {
case ConfigChangeNotification:
ret.add(sendConfigChangeNotification(session, (CEGWConfigChangeNotification) command));
break;
case CloseSessionRequest:
ret.add(closeSession(session, (CEGWCloseSessionRequest) command));
break;
case CheckRouting:
ret.add(checkEquipmentRouting(session, (CEGWRouteCheck) command));
break;
case BlinkRequest:
ret.add(processBlinkRequest(session, (CEGWBlinkRequest) command));
break;
case StartDebugEngine:
ret.add(processChangeRedirector(session, (CEGWStartDebugEngine) command));
break;
case FirmwareDownloadRequest:
ret.add(processFirmwareDownload(session, (CEGWFirmwareDownloadRequest) command));
break;
case FirmwareFlashRequest:
ret.add(processFirmwareFlash(session, (CEGWFirmwareFlashRequest) command));
break;
case RadioReset:
ret.add(processRadioReset(session, (CEGWRadioResetRequest) command));
break;
default:
LOG.warn("[{}] Failed to deliver command {}, unsupported command type", inventoryId, command);
ret.add(new EquipmentCommandResponse(
CEGWCommandResultCode.UnsupportedCommand, "Invalid command type ("
+ command.getCommandType() + ") for equipment (" + inventoryId + ")",
command, registeredGateway.getHostname(), registeredGateway.getPort()));
}
if (com.telecominfraproject.wlan.core.model.json.BaseJsonModel.hasUnsupportedValue(command)) {
LOG.error("[{}] Failed to deliver command {}, command contains unsupported value", inventoryId,
command);
ret.add(new EquipmentCommandResponse(CEGWCommandResultCode.UnsupportedCommand,
"Unsupported value in command for " + inventoryId, command, registeredGateway.getHostname(),
registeredGateway.getPort()));
return;
} }
OvsdbSession session = ovsdbSessionMapInterface.getSession(inventoryId);
if (session == null) {
LOG.warn("[{}] Failed to deliver command {}, equipment session not found", inventoryId, command);
ret.add(new EquipmentCommandResponse(CEGWCommandResultCode.NoRouteToCE,
"No session found for " + inventoryId, command, registeredGateway.getHostname(),
registeredGateway.getPort()));
return;
}
switch (command.getCommandType()) {
case ConfigChangeNotification:
ret.add(sendConfigChangeNotification(session, (CEGWConfigChangeNotification) command));
break;
case CloseSessionRequest:
ret.add(closeSession(session, (CEGWCloseSessionRequest) command));
break;
case CheckRouting:
ret.add(checkEquipmentRouting(session, (CEGWRouteCheck) command));
break;
case BlinkRequest:
ret.add(processBlinkRequest(session, (CEGWBlinkRequest) command));
break;
case StartDebugEngine:
ret.add(processChangeRedirector(session, (CEGWStartDebugEngine) command));
break;
case FirmwareDownloadRequest:
ret.add(processFirmwareDownload(session, (CEGWFirmwareDownloadRequest) command));
break;
case FirmwareFlashRequest:
ret.add(processFirmwareFlash(session, (CEGWFirmwareFlashRequest) command));
break;
case RadioReset:
ret.add(processRadioReset(session, (CEGWRadioResetRequest) command));
break;
default:
LOG.warn("[{}] Failed to deliver command {}, unsupported command type", inventoryId, command);
ret.add(new EquipmentCommandResponse(CEGWCommandResultCode.UnsupportedCommand,
"Invalid command type (" + command.getCommandType() + ") for equipment (" + inventoryId + ")",
command, registeredGateway.getHostname(), registeredGateway.getPort()));
}
}); });
return ret; return ret;
@@ -352,9 +357,9 @@ public class OpensyncCloudGatewayController {
try { try {
EquipmentGatewayRecord result = this.eqRoutingSvc.registerGateway(gwRecord); EquipmentGatewayRecord result = eqRoutingSvc.registerGateway(gwRecord);
this.registeredGwId = result.getId(); registeredGwId = result.getId();
this.registeredGateway = result; registeredGateway = result;
LOG.info("Successfully registered (name={}, id={}) with Routing Service", result.getHostname(), LOG.info("Successfully registered (name={}, id={}) with Routing Service", result.getHostname(),
registeredGwId); registeredGwId);
registeredWithRoutingService = true; registeredWithRoutingService = true;
@@ -383,20 +388,20 @@ public class OpensyncCloudGatewayController {
try { try {
eqRoutingSvc.deleteGateway(registeredGwId); eqRoutingSvc.deleteGateway(registeredGwId);
LOG.info("Deregistered Customer Equipment Gateway (name={},id={}) with Routing Service", LOG.info("Deregistered Customer Equipment Gateway (name={},id={}) with Routing Service",
getGatewayName(), this.registeredGwId); getGatewayName(), registeredGwId);
this.registeredGwId = -1; registeredGwId = -1;
this.registeredGateway = null; registeredGateway = null;
} catch (Exception e) { } catch (Exception e) {
// failed // failed
LOG.error("Failed to deregister Customer Equipment Gateway (name={},id={}) with Routing Service: {}", LOG.error("Failed to deregister Customer Equipment Gateway (name={},id={}) with Routing Service: {}",
getGatewayName(), this.registeredGwId, e.getLocalizedMessage()); getGatewayName(), registeredGwId, e.getLocalizedMessage());
} }
registeredWithRoutingService = false; registeredWithRoutingService = false;
} }
} }
public long getRegisteredGwId() { public long getRegisteredGwId() {
return this.registeredGwId; return registeredGwId;
} }
/** /**
@@ -418,7 +423,7 @@ public class OpensyncCloudGatewayController {
EquipmentRoutingRecord routingRecord = new EquipmentRoutingRecord(); EquipmentRoutingRecord routingRecord = new EquipmentRoutingRecord();
routingRecord.setCustomerId(customerId); routingRecord.setCustomerId(customerId);
routingRecord.setEquipmentId(equipmentId); routingRecord.setEquipmentId(equipmentId);
routingRecord.setGatewayId(this.registeredGwId); routingRecord.setGatewayId(registeredGwId);
try { try {
routingRecord = eqRoutingSvc.create(routingRecord); routingRecord = eqRoutingSvc.create(routingRecord);
@@ -456,7 +461,7 @@ public class OpensyncCloudGatewayController {
@Scheduled(initialDelay = 5 * 60 * 1000, fixedRate = 5 * 60 * 1000) @Scheduled(initialDelay = 5 * 60 * 1000, fixedRate = 5 * 60 * 1000)
public void updateActiveCustomer() { public void updateActiveCustomer() {
try { try {
Map<Integer, Long> activeMap = this.getActiveCustomerMapForUpdate(); Map<Integer, Long> activeMap = getActiveCustomerMapForUpdate();
if (null != activeMap) { if (null != activeMap) {
LOG.info("Updating active customer records, total record size {}", activeMap.size()); LOG.info("Updating active customer records, total record size {}", activeMap.size());
// this.eqRoutingSvc.updateActiveCustomer(activeMap, // this.eqRoutingSvc.updateActiveCustomer(activeMap,
@@ -482,11 +487,11 @@ public class OpensyncCloudGatewayController {
* @param customerId * @param customerId
*/ */
public void updateActiveCustomer(int customerId) { public void updateActiveCustomer(int customerId) {
this.activeCustomerReadLock.lock(); activeCustomerReadLock.lock();
try { try {
this.activeCustomerMap.merge(customerId, System.currentTimeMillis(), latestTimestamp); activeCustomerMap.merge(customerId, System.currentTimeMillis(), latestTimestamp);
} finally { } finally {
this.activeCustomerReadLock.unlock(); activeCustomerReadLock.unlock();
} }
} }
@@ -496,17 +501,17 @@ public class OpensyncCloudGatewayController {
* @return null if no records. * @return null if no records.
*/ */
protected Map<Integer, Long> getActiveCustomerMapForUpdate() { protected Map<Integer, Long> getActiveCustomerMapForUpdate() {
this.activeCustomerWriteLock.lock(); activeCustomerWriteLock.lock();
try { try {
Map<Integer, Long> map = null; Map<Integer, Long> map = null;
if (!this.activeCustomerMap.isEmpty()) { if (!activeCustomerMap.isEmpty()) {
map = this.activeCustomerMap; map = activeCustomerMap;
this.activeCustomerMap = new ConcurrentHashMap<>(); activeCustomerMap = new ConcurrentHashMap<>();
} }
return map; return map;
} finally { } finally {
this.activeCustomerWriteLock.unlock(); activeCustomerWriteLock.unlock();
} }
} }
} }

View File

@@ -3,8 +3,9 @@ package com.telecominfraproject.wlan.opensync.external.integration.models;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class ConnectNodeInfo implements Cloneable{ public class ConnectNodeInfo implements Cloneable {
public Map<String,String> mqttSettings; public Map<String, String> mqttSettings;
public Map<String, Map<String,String>> wifiRadioStates;
public String redirectorAddr; public String redirectorAddr;
public String managerAddr; public String managerAddr;
public String skuNumber; public String skuNumber;
@@ -15,29 +16,35 @@ public class ConnectNodeInfo implements Cloneable{
public String firmwareVersion; public String firmwareVersion;
public String revision; public String revision;
public String model; public String model;
public String ifName;
public String ifType;
public String country;
@Override @Override
public ConnectNodeInfo clone() { public ConnectNodeInfo clone() {
try { try {
ConnectNodeInfo ret = (ConnectNodeInfo)super.clone(); ConnectNodeInfo ret = (ConnectNodeInfo) super.clone();
if (this.mqttSettings!=null) { if (this.mqttSettings != null) {
ret.mqttSettings = new HashMap<>(this.mqttSettings); ret.mqttSettings = new HashMap<>(this.mqttSettings);
} }
if (this.wifiRadioStates != null) {
ret.wifiRadioStates = new HashMap<>(this.wifiRadioStates);
}
return ret; return ret;
}catch(CloneNotSupportedException e) { } catch (CloneNotSupportedException e) {
throw new IllegalStateException("Cannot clone ", e); throw new IllegalStateException("Cannot clone ", e);
} }
} }
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(
"ConnectNodeInfo [mqttSettings=%s, redirectorAddr=%s, managerAddr=%s, skuNumber=%s, serialNumber=%s, " "ConnectNodeInfo [mqttSettings=%s, redirectorAddr=%s, managerAddr=%s, skuNumber=%s, serialNumber=%s, "
+ "macAddress=%s, ipV4Address=%s, platformVersion=%s, firmwareVersion=%s, revision=%s, model=%s]", + "macAddress=%s, ipV4Address=%s, platformVersion=%s, firmwareVersion=%s, revision=%s, model=%s ifName=%s ifType=%s, wifiRadioStates=%s]",
mqttSettings, redirectorAddr, managerAddr, skuNumber, serialNumber, macAddress, ipV4Address, mqttSettings, redirectorAddr, managerAddr, skuNumber, serialNumber, macAddress, ipV4Address,
platformVersion, firmwareVersion, revision, model); platformVersion, firmwareVersion, revision, model, ifName, ifType, wifiRadioStates);
} }
} }

View File

@@ -38,196 +38,221 @@ import wc.stats.IpDnsTelemetry.WCStatsReport;
@Component @Component
public class OpensyncMqttClient implements ApplicationListener<ContextClosedEvent> { public class OpensyncMqttClient implements ApplicationListener<ContextClosedEvent> {
private static final Logger LOG = LoggerFactory.getLogger(OpensyncMqttClient.class); private static final Logger LOG = LoggerFactory.getLogger(OpensyncMqttClient.class);
private static final Logger MQTT_LOG = LoggerFactory.getLogger("MQTT_DATA"); private static final Logger MQTT_LOG = LoggerFactory.getLogger("MQTT_DATA");
public static Charset utf8 = Charset.forName("UTF-8"); public static Charset utf8 = Charset.forName("UTF-8");
@Autowired @Autowired
private OpensyncExternalIntegrationInterface extIntegrationInterface; private OpensyncExternalIntegrationInterface extIntegrationInterface;
// //
// See https://github.com/fusesource/mqtt-client for the docs // See https://github.com/fusesource/mqtt-client for the docs
// //
private boolean keepReconnecting = true; private boolean keepReconnecting = true;
private Thread mqttClientThread; private Thread mqttClientThread;
public OpensyncMqttClient(@Autowired io.netty.handler.ssl.SslContext sslContext, public OpensyncMqttClient(@Autowired io.netty.handler.ssl.SslContext sslContext,
@Value("${connectus.mqttBroker.address:testportal.123wlan.com}") String mqttBrokerAddress, @Value("${connectus.mqttBroker.address:testportal.123wlan.com}") String mqttBrokerAddress,
@Value("${connectus.mqttBroker.listenPort:1883}") int mqttBrokerListenPort, @Value("${connectus.mqttBroker.listenPort:1883}") int mqttBrokerListenPort,
@Value("${connectus.mqttBroker.user:admin}") String username, @Value("${connectus.mqttBroker.user:admin}") String username,
@Value("${connectus.mqttBroker.password:admin}") String password, @Value("${connectus.mqttBroker.password:admin}") String password,
@Value("${mqtt.javax.net.ssl.keyStore:/opt/tip-wlan/certs/client_keystore.jks}") String jdkKeyStoreLocation, @Value("${mqtt.javax.net.ssl.keyStore:/opt/tip-wlan/certs/client_keystore.jks}") String jdkKeyStoreLocation,
@Value("${mqtt.javax.net.ssl.keyStorePassword:mypassword}") String jdkKeyStorePassword, @Value("${mqtt.javax.net.ssl.keyStorePassword:mypassword}") String jdkKeyStorePassword,
@Value("${mqtt.javax.net.ssl.trustStore:/opt/tip-wlan/certs/truststore.jks}") String jdkTrustStoreLocation, @Value("${mqtt.javax.net.ssl.trustStore:/opt/tip-wlan/certs/truststore.jks}") String jdkTrustStoreLocation,
@Value("${mqtt.javax.net.ssl.trustStorePassword:mypassword}") String jdkTrustStorePassword) { @Value("${mqtt.javax.net.ssl.trustStorePassword:mypassword}") String jdkTrustStorePassword) {
if (System.getProperty("javax.net.ssl.keyStore") == null) { if (System.getProperty("javax.net.ssl.keyStore") == null) {
System.setProperty("javax.net.ssl.keyStore", jdkKeyStoreLocation); System.setProperty("javax.net.ssl.keyStore", jdkKeyStoreLocation);
} }
if (System.getProperty("javax.net.ssl.keyStorePassword") == null) { if (System.getProperty("javax.net.ssl.keyStorePassword") == null) {
System.setProperty("javax.net.ssl.keyStorePassword", jdkKeyStorePassword); System.setProperty("javax.net.ssl.keyStorePassword", jdkKeyStorePassword);
} }
if (System.getProperty("javax.net.ssl.trustStore") == null) { if (System.getProperty("javax.net.ssl.trustStore") == null) {
System.setProperty("javax.net.ssl.trustStore", jdkTrustStoreLocation); System.setProperty("javax.net.ssl.trustStore", jdkTrustStoreLocation);
} }
if (System.getProperty("javax.net.ssl.trustStorePassword") == null) { if (System.getProperty("javax.net.ssl.trustStorePassword") == null) {
System.setProperty("javax.net.ssl.trustStorePassword", jdkTrustStorePassword); System.setProperty("javax.net.ssl.trustStorePassword", jdkTrustStorePassword);
} }
Runnable mqttClientRunnable = () -> { Runnable mqttClientRunnable = new Runnable() {
while (keepReconnecting) { @Override
BlockingConnection connection = null; public void run() {
try { while (keepReconnecting) {
Thread.sleep(5000); BlockingConnection connection = null;
try {
Thread.sleep(5000);
// Create a new MQTT connection to the broker. // Create a new MQTT connection to the broker.
/* /*
* Using SSL connections If you want to connect over SSL/TLS instead of TCP, use * Using SSL connections If you want to connect over
* an "ssl://" or "tls://" URI prefix instead of "tcp://" for the host field. * SSL/TLS instead of TCP, use an "ssl://" or "tls://"
* Supported protocol values are: * URI prefix instead of "tcp://" for the host field.
* * Supported protocol values are:
* ssl:// - Use the JVM default version of the SSL algorithm. sslv*:// - Use a *
* specific SSL version where * is a version supported by your JVM. Example: * ssl:// - Use the JVM default version of the SSL
* sslv3 tls:// - Use the JVM default version of the TLS algorithm. tlsv*:// - * algorithm. sslv*:// - Use a specific SSL version
* Use a specific TLS version where * is a version supported by your JVM. * where * is a version supported by your JVM. Example:
* Example: tlsv1.1 The client will use the default JVM SSLContext which is * sslv3 tls:// - Use the JVM default version of the TLS
* configured via JVM system properties unless you configure the MQTT instance * algorithm. tlsv*:// - Use a specific TLS version
* using the setSslContext method. * where * is a version supported by your JVM. Example:
* * tlsv1.1 The client will use the default JVM
* SSL connections perform blocking operations against internal thread pool * SSLContext which is configured via JVM system
* unless you call the setBlockingExecutor method to configure that executor * properties unless you configure the MQTT instance
* they will use instead. * using the setSslContext method.
* *
*/ * SSL connections perform blocking operations against
* internal thread pool unless you call the
* setBlockingExecutor method to configure that executor
* they will use instead.
*
*/
MQTT mqtt = new MQTT(); MQTT mqtt = new MQTT();
// mqtt.setHost("tcp://192.168.0.137:61616"); // mqtt.setHost("tcp://192.168.0.137:61616");
mqtt.setHost("tls://" + mqttBrokerAddress + ":" + mqttBrokerListenPort); mqtt.setHost("tls://" + mqttBrokerAddress + ":" + mqttBrokerListenPort);
LOG.info("Connecting to MQTT broker at {}", mqtt.getHost()); LOG.info("Connecting to MQTT broker at {}", mqtt.getHost());
mqtt.setClientId("opensync_mqtt"); mqtt.setClientId("opensync_mqtt");
mqtt.setUserName(username); mqtt.setUserName(username);
mqtt.setPassword(password); mqtt.setPassword(password);
// Note: the following does not work with the serverContext, it has to be the // Note: the following does not work with the
// clientContext // serverContext,
// mqtt.setSslContext(((JdkSslContext) sslContext).context()); // it has to be the
// For now we'll rely on regular SSLContext from the JDK // clientContext
// mqtt.setSslContext(((JdkSslContext)
// sslContext).context());
// For now we'll rely on regular SSLContext from the JDK
// TODO: revisit this blocking connection, change it to futureConnection // TODO: revisit this blocking connection, change it to
connection = mqtt.blockingConnection(); // futureConnection
connection.connect(); connection = mqtt.blockingConnection();
LOG.info("Connected to MQTT broker at {}", mqtt.getHost()); connection.connect();
LOG.info("Connected to MQTT broker at {}", mqtt.getHost());
// Subscribe to topics: // Subscribe to topics:
// //
// new Topic("mqtt/example/publish", QoS.AT_LEAST_ONCE), // new Topic("mqtt/example/publish", QoS.AT_LEAST_ONCE),
// new Topic("#", QoS.AT_LEAST_ONCE), // new Topic("#", QoS.AT_LEAST_ONCE),
// new Topic("test/#", QoS.EXACTLY_ONCE), // new Topic("test/#", QoS.EXACTLY_ONCE),
// new Topic("foo/+/bar", QoS.AT_LEAST_ONCE) // new Topic("foo/+/bar", QoS.AT_LEAST_ONCE)
Topic[] topics = { new Topic("#", QoS.AT_LEAST_ONCE), }; Topic[] topics = { new Topic("#", QoS.AT_LEAST_ONCE), };
connection.subscribe(topics); connection.subscribe(topics);
LOG.info("Subscribed to mqtt topics {}", Arrays.asList(topics)); LOG.info("Subscribed to mqtt topics {}", Arrays.asList(topics));
// prepare a JSONPrinter to format protobuf messages as json // prepare a JSONPrinter to format protobuf messages as
List<Descriptors.Descriptor> protobufDescriptors = new ArrayList<>(); // json
protobufDescriptors.addAll(OpensyncStats.getDescriptor().getMessageTypes()); List<Descriptors.Descriptor> protobufDescriptors = new ArrayList<>();
protobufDescriptors.addAll(IpDnsTelemetry.getDescriptor().getMessageTypes()); protobufDescriptors.addAll(OpensyncStats.getDescriptor().getMessageTypes());
protobufDescriptors.addAll(NetworkMetadata.getDescriptor().getMessageTypes()); protobufDescriptors.addAll(IpDnsTelemetry.getDescriptor().getMessageTypes());
TypeRegistry oldRegistry = TypeRegistry.newBuilder().add(protobufDescriptors).build(); protobufDescriptors.addAll(NetworkMetadata.getDescriptor().getMessageTypes());
JsonFormat.Printer jsonPrinter = JsonFormat.printer().includingDefaultValueFields() TypeRegistry oldRegistry = TypeRegistry.newBuilder().add(protobufDescriptors).build();
.omittingInsignificantWhitespace().usingTypeRegistry(oldRegistry); JsonFormat.Printer jsonPrinter = JsonFormat.printer().includingDefaultValueFields()
.omittingInsignificantWhitespace().usingTypeRegistry(oldRegistry);
// main loop - receive messages // main loop - receive messages
while (true) { while (true) {
Message mqttMsg = connection.receive(5, TimeUnit.SECONDS); Message mqttMsg = connection.receive(5, TimeUnit.SECONDS);
if (mqttMsg == null) { if (mqttMsg == null) {
continue; continue;
} }
byte payload[] = mqttMsg.getPayload(); byte payload[] = mqttMsg.getPayload();
// we acknowledge right after receive because: // we acknowledge right after receive because:
// a. none of the stats messages are so important that we cannot skip one // a. none of the stats messages are so important
// b. if there's some kind of problem with the message (decoding or processing) // that
// - we want to move on as quickly as possible and not let it get stuck in the // we cannot skip one
// queue // b. if there's some kind of problem with the
mqttMsg.ack(); // message
// (decoding or processing)
// - we want to move on as quickly as possible and
// not
// let it get stuck in the
// queue
mqttMsg.ack();
LOG.trace("received message on topic {} size {}", mqttMsg.getTopic(), payload.length); LOG.trace("received message on topic {} size {}", mqttMsg.getTopic(), payload.length);
if (payload[0] == 0x78) { if (payload[0] == 0x78) {
// looks like zlib-compressed data, let's decompress it before deserializing // looks like zlib-compressed data, let's
payload = ZlibUtil.decompress(payload); // decompress
} // it before deserializing
payload = ZlibUtil.decompress(payload);
}
// attempt to parse the message as protobuf // attempt to parse the message as protobuf
MessageOrBuilder encodedMsg = null; MessageOrBuilder encodedMsg = null;
try { try {
encodedMsg = Report.parseFrom(payload); encodedMsg = Report.parseFrom(payload);
MQTT_LOG.info("topic = {} Report = {}", mqttMsg.getTopic(), jsonPrinter.print(encodedMsg)); MQTT_LOG.info("topic = {} Report = {}", mqttMsg.getTopic(),
extIntegrationInterface.processMqttMessage(mqttMsg.getTopic(), (Report) encodedMsg); jsonPrinter.print(encodedMsg));
extIntegrationInterface.processMqttMessage(mqttMsg.getTopic(), (Report) encodedMsg);
} catch (Exception e) { } catch (Exception e) {
try { try {
// not a plume_stats report, attempt to deserialize as network_metadata // not a plume_stats report, attempt to
encodedMsg = FlowReport.parseFrom(payload); // deserialize as network_metadata
MQTT_LOG.info("topic = {} FlowReport = {}", mqttMsg.getTopic(), encodedMsg = FlowReport.parseFrom(payload);
jsonPrinter.print(encodedMsg)); MQTT_LOG.info("topic = {} FlowReport = {}", mqttMsg.getTopic(),
extIntegrationInterface.processMqttMessage(mqttMsg.getTopic(), (FlowReport) encodedMsg); jsonPrinter.print(encodedMsg));
} catch (Exception e1) { extIntegrationInterface.processMqttMessage(mqttMsg.getTopic(),
(FlowReport) encodedMsg);
} catch (Exception e1) {
try { try {
// not a plume_stats report and not network_metadata report, attempt to // not a plume_stats report and not
// deserialize as WCStatsReport // network_metadata report, attempt to
encodedMsg = WCStatsReport.parseFrom(payload); // deserialize as WCStatsReport
MQTT_LOG.info("topic = {} IpDnsTelemetry = {}", mqttMsg.getTopic(), encodedMsg = WCStatsReport.parseFrom(payload);
jsonPrinter.print(encodedMsg)); MQTT_LOG.info("topic = {} IpDnsTelemetry = {}", mqttMsg.getTopic(),
extIntegrationInterface.processMqttMessage(mqttMsg.getTopic(), jsonPrinter.print(encodedMsg));
(WCStatsReport) encodedMsg); extIntegrationInterface.processMqttMessage(mqttMsg.getTopic(),
} catch (Exception e2) { (WCStatsReport) encodedMsg);
String msgStr = new String(mqttMsg.getPayload(), utf8); } catch (Exception e2) {
MQTT_LOG.info("topic = {} message = {}", mqttMsg.getTopic(), msgStr); String msgStr = new String(mqttMsg.getPayload(), utf8);
} MQTT_LOG.info("topic = {} message = {}", mqttMsg.getTopic(), msgStr);
} }
} }
}
} }
} catch (Exception e) { } catch (Exception e) {
LOG.error("Exception in MQTT receiver", e); LOG.error("Exception in MQTT receiver", e);
} finally { } finally {
try { try {
if (connection != null) { if (connection != null) {
connection.disconnect(); connection.disconnect();
} }
} catch (Exception e1) { } catch (Exception e1) {
// do nothing // do nothing
} }
} }
} }
}; }
};
mqttClientThread = new Thread(mqttClientRunnable, "mqttClientThread"); mqttClientThread = new Thread(mqttClientRunnable, "mqttClientThread");
mqttClientThread.setDaemon(true); mqttClientThread.setDaemon(true);
mqttClientThread.start(); mqttClientThread.start();
} }
@Override @Override
public void onApplicationEvent(ContextClosedEvent event) { public void onApplicationEvent(ContextClosedEvent event) {
LOG.debug("Processing ContextClosedEvent event"); LOG.debug("Processing ContextClosedEvent event");
keepReconnecting = false; keepReconnecting = false;
if (mqttClientThread != null) { if (mqttClientThread != null) {
mqttClientThread.interrupt(); mqttClientThread.interrupt();
} }
} }
} }

View File

@@ -97,7 +97,7 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
// with the serialNumber and using it as a key (equivalent // with the serialNumber and using it as a key (equivalent
// of KDC unique qrCode) // of KDC unique qrCode)
String key = clientCn + "_" + connectNodeInfo.serialNumber; String key = clientCn + "_" + connectNodeInfo.serialNumber;
ConnectusOvsdbClient.this.ovsdbSessionMapInterface.newSession(key, ovsdbClient); ovsdbSessionMapInterface.newSession(key, ovsdbClient);
extIntegrationInterface.apConnected(key, connectNodeInfo); extIntegrationInterface.apConnected(key, connectNodeInfo);
// push configuration to AP // push configuration to AP
@@ -105,8 +105,7 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
monitorOvsdbStateTables(ovsdbClient, key); monitorOvsdbStateTables(ovsdbClient, key);
LOG.info("ovsdbClient connected from {} on port {} key {} ", remoteHost, localPort, key); LOG.info("ovsdbClient connected from {} on port {} key {} ", remoteHost, localPort, key);
LOG.info("ovsdbClient connectedClients = {}", LOG.info("ovsdbClient connectedClients = {}", ovsdbSessionMapInterface.getNumSessions());
ConnectusOvsdbClient.this.ovsdbSessionMapInterface.getNumSessions());
} catch (Exception e) { } catch (Exception e) {
LOG.error("ovsdbClient error", e); LOG.error("ovsdbClient error", e);
@@ -139,7 +138,7 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
// so we are doing a reverse lookup here, and then if we find // so we are doing a reverse lookup here, and then if we find
// the key we will // the key we will
// remove the entry from the connectedClients. // remove the entry from the connectedClients.
String key = ConnectusOvsdbClient.this.ovsdbSessionMapInterface.lookupClientId(ovsdbClient); String key = ovsdbSessionMapInterface.lookupClientId(ovsdbClient);
if (key != null) { if (key != null) {
try { try {
@@ -155,7 +154,7 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
} }
try { try {
extIntegrationInterface.apDisconnected(key); extIntegrationInterface.apDisconnected(key);
ConnectusOvsdbClient.this.ovsdbSessionMapInterface.removeSession(key); ovsdbSessionMapInterface.removeSession(key);
} catch (Exception e) { } catch (Exception e) {
LOG.debug("Unable to process ap disconnect. {}", e.getMessage()); LOG.debug("Unable to process ap disconnect. {}", e.getMessage());
} finally { } finally {
@@ -165,8 +164,7 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
LOG.info("ovsdbClient disconnected from {} on port {} clientCn {} key {} ", remoteHost, localPort, LOG.info("ovsdbClient disconnected from {} on port {} clientCn {} key {} ", remoteHost, localPort,
clientCn, key); clientCn, key);
LOG.info("ovsdbClient connectedClients = {}", LOG.info("ovsdbClient connectedClients = {}", ovsdbSessionMapInterface.getNumSessions());
ConnectusOvsdbClient.this.ovsdbSessionMapInterface.getNumSessions());
} }
}; };
@@ -182,8 +180,8 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
LOG.debug("Starting Client connect"); LOG.debug("Starting Client connect");
connectNodeInfo = ovsdbDao.updateConnectNodeInfoOnConnect(ovsdbClient, clientCn, connectNodeInfo); connectNodeInfo = ovsdbDao.updateConnectNodeInfoOnConnect(ovsdbClient, clientCn, connectNodeInfo);
String apId = clientCn + "_" + connectNodeInfo.serialNumber; ovsdbDao.vifBridge = connectNodeInfo.ifName;
OpensyncAPConfig opensyncAPConfig = extIntegrationInterface.getApConfig(apId);
try { try {
ovsdbDao.provisionBridgePortInterface(ovsdbClient); ovsdbDao.provisionBridgePortInterface(ovsdbClient);
@@ -193,10 +191,12 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
} }
ovsdbDao.removeAllSsids(ovsdbClient); // always ovsdbDao.removeAllSsids(ovsdbClient); // always
String apId = clientCn + "_" + connectNodeInfo.serialNumber;
OpensyncAPConfig opensyncAPConfig = extIntegrationInterface.getApConfig(apId);
if (opensyncAPConfig != null) { if (opensyncAPConfig != null) {
ovsdbDao.configureWifiRadios(ovsdbClient, opensyncAPConfig); ovsdbDao.configureWifiRadios(ovsdbClient, opensyncAPConfig);
ovsdbDao.configureSsids(ovsdbClient, opensyncAPConfig); ovsdbDao.configureSsids(ovsdbClient, opensyncAPConfig);
ovsdbDao.configureWifiInet(ovsdbClient, opensyncAPConfig);
} }
ovsdbDao.configureStats(ovsdbClient); ovsdbDao.configureStats(ovsdbClient);
@@ -208,8 +208,6 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
ovsdbDao.updateDeviceStatsReportingInterval(ovsdbClient, collectionIntervalSecDeviceStats); ovsdbDao.updateDeviceStatsReportingInterval(ovsdbClient, collectionIntervalSecDeviceStats);
} }
// ovsdbDao.configureWifiInet(ovsdbClient);
LOG.debug("Client connect Done"); LOG.debug("Client connect Done");
return connectNodeInfo; return connectNodeInfo;
} }
@@ -307,22 +305,22 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
for (Entry<UUID, RowUpdate> rowUpdate : tableUpdate.getValue().getRowUpdates() for (Entry<UUID, RowUpdate> rowUpdate : tableUpdate.getValue().getRowUpdates()
.entrySet()) { .entrySet()) {
if (rowUpdate.getValue().getOld() != null if ((rowUpdate.getValue().getOld() != null)
&& rowUpdate.getValue().getNew() == null) { && (rowUpdate.getValue().getNew() == null)) {
Row row = rowUpdate.getValue().getOld(); Row row = rowUpdate.getValue().getOld();
String ifName = null; String ifName = null;
String ssid = null; String ssid = null;
if (row.getColumns().get("ssid") != null if ((row.getColumns().get("ssid") != null)
&& row.getColumns().get("ssid").getClass().equals( && row.getColumns().get("ssid").getClass().equals(
com.vmware.ovsdb.protocol.operation.notation.Atom.class)) { com.vmware.ovsdb.protocol.operation.notation.Atom.class)) {
ssid = row.getStringColumn("ssid"); ssid = row.getStringColumn("ssid");
} }
if (row.getColumns().get("if_name") != null if ((row.getColumns().get("if_name") != null)
&& row.getColumns().get("if_name").getClass().equals( && row.getColumns().get("if_name").getClass().equals(
com.vmware.ovsdb.protocol.operation.notation.Atom.class)) { com.vmware.ovsdb.protocol.operation.notation.Atom.class)) {
ifName = row.getStringColumn("if_name"); ifName = row.getStringColumn("if_name");
} }
if (ifName != null && ssid != null) { if ((ifName != null) && (ssid != null)) {
OpensyncAPVIFState toBeDeleted = new OpensyncAPVIFState(); OpensyncAPVIFState toBeDeleted = new OpensyncAPVIFState();
toBeDeleted.setSsid(ssid); toBeDeleted.setSsid(ssid);
toBeDeleted.setIfName(ifName); toBeDeleted.setIfName(ifName);
@@ -333,7 +331,7 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
} }
if (tableUpdate.getValue().getRowUpdates().values().isEmpty()) { if (tableUpdate.getValue().getRowUpdates().isEmpty()) {
tableUpdates.getTableUpdates().remove(tableUpdate.getKey()); tableUpdates.getTableUpdates().remove(tableUpdate.getKey());
} }
@@ -378,7 +376,7 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
for (TableUpdate tableUpdate : tableUpdates.getTableUpdates().values()) { for (TableUpdate tableUpdate : tableUpdates.getTableUpdates().values()) {
for (RowUpdate rowUpdate : tableUpdate.getRowUpdates().values()) { for (RowUpdate rowUpdate : tableUpdate.getRowUpdates().values()) {
if (rowUpdate.getOld() != null && rowUpdate.getNew() == null) { if ((rowUpdate.getOld() != null) && (rowUpdate.getNew() == null)) {
Row row = rowUpdate.getOld(); Row row = rowUpdate.getOld();
String deletedClientMac = row.getStringColumn("mac"); String deletedClientMac = row.getStringColumn("mac");
extIntegrationInterface.wifiAssociatedClientsDbTableDelete(deletedClientMac, extIntegrationInterface.wifiAssociatedClientsDbTableDelete(deletedClientMac,