diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbClient.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbClient.java index 2a073c2..0355e7e 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbClient.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/TipWlanOvsdbClient.java @@ -41,7 +41,6 @@ import com.vmware.ovsdb.protocol.methods.RowUpdate; import com.vmware.ovsdb.protocol.methods.TableUpdate; import com.vmware.ovsdb.protocol.methods.TableUpdates; import com.vmware.ovsdb.protocol.operation.notation.Row; -import com.vmware.ovsdb.protocol.operation.notation.Value; import com.vmware.ovsdb.service.OvsdbClient; import com.vmware.ovsdb.service.OvsdbPassiveConnectionListener; @@ -346,6 +345,13 @@ public class TipWlanOvsdbClient implements OvsdbClientInterface { } catch (OvsdbClientException e) { LOG.debug("Could not enable monitor for DHCP_leased_IP table. {}", e.getMessage()); + } + + try { + monitorCommandStateDbTable(ovsdbClient, key); + } catch (OvsdbClientException e) { + LOG.debug("Could not enable monitor for Command_State table. {}", e.getMessage()); + } LOG.debug("Finished (re)setting monitors for AP {}", key); @@ -427,6 +433,85 @@ public class TipWlanOvsdbClient implements OvsdbClientInterface { awCf.join(); + } + + + private void monitorCommandStateDbTable(OvsdbClient ovsdbClient, String key) throws OvsdbClientException { + + CompletableFuture csCf = ovsdbClient.monitor(OvsdbDao.ovsdbName, + OvsdbDao.commandStateDbTable + "_" + key, + new MonitorRequests(ImmutableMap.of(OvsdbDao.commandStateDbTable, new MonitorRequest())), + new MonitorCallback() { + + @Override + public void update(TableUpdates tableUpdates) { + LOG.info(OvsdbDao.commandStateDbTable + "_" + key + " monitor callback received {}", + tableUpdates); + + List> insert = new ArrayList<>(); + List> delete = new ArrayList<>(); + List> update = new ArrayList<>(); + + + for (TableUpdate tableUpdate : tableUpdates.getTableUpdates().values()) { + for (RowUpdate rowUpdate : tableUpdate.getRowUpdates().values()) { + + if (rowUpdate.getNew() == null) { + Map rowMap = new HashMap<>(); + + rowUpdate.getOld().getColumns().entrySet().stream().forEach(c -> { + rowMap.put(c.getKey(), c.getValue().toString()); + }); + + delete.add(rowMap); + // delete + } else if (rowUpdate.getOld() == null) { + // insert + Map rowMap = new HashMap<>(); + + rowUpdate.getNew().getColumns().entrySet().stream().forEach(c -> { + rowMap.put(c.getKey(), c.getValue().toString()); + }); + + insert.add(rowMap); + } else { + + // insert + Map rowMap = new HashMap<>(); + + rowUpdate.getOld().getColumns().putAll(rowUpdate.getNew().getColumns()); + rowUpdate.getOld().getColumns().entrySet().stream().forEach(c -> { + rowMap.put(c.getKey(), c.getValue().toString()); + }); + + update.add(rowMap); + + } + } + } + + if (!insert.isEmpty()) { + extIntegrationInterface.commandStateDbTableUpdate(insert, key, RowUpdateOperation.INSERT); + } + + if (!delete.isEmpty()) { + extIntegrationInterface.commandStateDbTableUpdate(delete, key, RowUpdateOperation.DELETE); + + } + + if (!update.isEmpty()) { + extIntegrationInterface.commandStateDbTableUpdate(update, key, RowUpdateOperation.MODIFY); + + } + + } + + + }); + + csCf.join(); + + } private void monitorAwlanNodeDbTable(OvsdbClient ovsdbClient, String key) throws OvsdbClientException { diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbDao.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbDao.java index 1086c98..cd3346a 100644 --- a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbDao.java +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/OvsdbDao.java @@ -43,6 +43,7 @@ import com.telecominfraproject.wlan.opensync.external.integration.models.Opensyn import com.telecominfraproject.wlan.opensync.external.integration.models.OpensyncAWLANNode; import com.telecominfraproject.wlan.opensync.external.integration.models.OpensyncWifiAssociatedClients; import com.telecominfraproject.wlan.opensync.ovsdb.dao.models.BridgeInfo; +import com.telecominfraproject.wlan.opensync.ovsdb.dao.models.CommandConfigInfo; import com.telecominfraproject.wlan.opensync.ovsdb.dao.models.InterfaceInfo; import com.telecominfraproject.wlan.opensync.ovsdb.dao.models.PortInfo; import com.telecominfraproject.wlan.opensync.ovsdb.dao.models.WifiInetConfigInfo; @@ -172,6 +173,10 @@ public class OvsdbDao { public static final String dhcpLeasedIpDbTable = "DHCP_leased_IP"; + public static final String commandConfigDbTable = "Command_Config"; + + public static final String commandStateDbTable = "Command_State"; + public ConnectNodeInfo getConnectNodeInfo(OvsdbClient ovsdbClient) { ConnectNodeInfo ret = new ConnectNodeInfo(); @@ -983,6 +988,58 @@ public class OvsdbDao { return ret; } + + public Map getProvisionedCommandConfigs(OvsdbClient ovsdbClient) { + Map ret = new HashMap<>(); + + List operations = new ArrayList<>(); + List conditions = new ArrayList<>(); + List columns = new ArrayList<>(); + + columns.add("_uuid"); + columns.add("delay"); + columns.add("duration"); + columns.add("command"); + columns.add("payload"); + columns.add("timestamp"); + + + try { + LOG.debug("Retrieving CommandConfig:"); + + operations.add(new Select(commandConfigDbTable, conditions, columns)); + CompletableFuture fResult = ovsdbClient.transact(ovsdbName, operations); + OperationResult[] result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS); + + for (OperationResult res : result) { + LOG.debug("Op Result {}", res); + } + + for (Row row : ((SelectResult) result[0]).getRows()) { + + CommandConfigInfo commandConfigInfo = new CommandConfigInfo(); + commandConfigInfo.uuid = row.getUuidColumn("_uuid"); + commandConfigInfo.delay = row.getIntegerColumn("delay"); + commandConfigInfo.duration = row.getIntegerColumn("duration"); + commandConfigInfo.command = row.getStringColumn("command"); + commandConfigInfo.payload = row.getMapColumn("payload"); + commandConfigInfo.timestamp = row.getIntegerColumn("timestamp"); + + ret.put(commandConfigInfo.command, commandConfigInfo); + } + + LOG.debug("Retrieved CommandConfig: {}", ret); + + } catch (ExecutionException | InterruptedException | OvsdbClientException | TimeoutException e) { + + LOG.error("Error in getProvisionedCommandConfigs", e); + + throw new RuntimeException(e); + } + + return ret; + + } public Map getProvisionedWifiRadioConfigs(OvsdbClient ovsdbClient) { Map ret = new HashMap<>(); @@ -2142,6 +2199,46 @@ public class OvsdbDao { } + public void configureCommands(OvsdbClient ovsdbClient, String command, Map payload, Long delay, + Long duration) { + + + List operations = new ArrayList<>(); + Map commandConfigColumns = new HashMap<>(); + List conditions = new ArrayList<>(); + conditions.add(new Condition("command", Function.EQUALS, new Atom<>(command))); + + commandConfigColumns.put("command", new Atom<>(command)); + commandConfigColumns.put("payload", com.vmware.ovsdb.protocol.operation.notation.Map.of(payload)); + + commandConfigColumns.put("delay", new Atom<>(delay)); + commandConfigColumns.put("duration", new Atom<>(delay)); + + Row row = new Row(commandConfigColumns); + if (getProvisionedCommandConfigs(ovsdbClient).containsKey(command)) { + operations.add(new Update(commandConfigDbTable, conditions, row)); + } else { + operations.add(new Insert(commandConfigDbTable, row)); + } + + + try { + CompletableFuture fResult = ovsdbClient.transact(ovsdbName, operations); + OperationResult[] result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS); + + LOG.debug("Configured command {} for duration {} payload {}", command, duration, payload); + + for (OperationResult res : result) { + LOG.debug("Op Result {}", res); + } + } catch (OvsdbClientException | InterruptedException | ExecutionException | TimeoutException e) { + LOG.error("configureCommands interrupted.", e); + throw new RuntimeException(e); + + } + + + } private void configureWifiRadios(OvsdbClient ovsdbClient, String freqBand, int channel, Map hwConfig, String country, int beaconInterval, boolean enabled, String hwMode, @@ -2602,7 +2699,7 @@ public class OvsdbDao { } else if (ssidSecurityMode.equals("wpaEAP") || ssidSecurityMode.equals("wpa2EAP") || ssidSecurityMode.equals("wpa2OnlyEAP")) { opensyncSecurityMode = "WPA-EAP"; - } else if (ssidSecurityMode.equals("wpaRadius") || ssidSecurityMode.equals("wpa2OnlyRadius") + } else if (ssidSecurityMode.equals("wpaRadius") || ssidSecurityMode.equals("wpa2OnlyRadius") || ssidSecurityMode.equals("wpa2Radius")) { opensyncSecurityMode = "WPA-EAP"; } @@ -2906,7 +3003,7 @@ public class OvsdbDao { // broadcast } if (ipAssignScheme.equals("dhcp")) { - insertColumns.put("dhcp_sniff", new Atom<>(true)); + insertColumns.put("dhcp_sniff", new Atom<>(true)); } else { insertColumns.put("dhcp_sniff", new Atom<>(false)); } diff --git a/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/CommandConfigInfo.java b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/CommandConfigInfo.java new file mode 100644 index 0000000..aa357a8 --- /dev/null +++ b/opensync-gateway/src/main/java/com/telecominfraproject/wlan/opensync/ovsdb/dao/models/CommandConfigInfo.java @@ -0,0 +1,37 @@ +package com.telecominfraproject.wlan.opensync.ovsdb.dao.models; + +import java.util.HashMap; +import java.util.Map; + +import com.vmware.ovsdb.protocol.operation.notation.Uuid; + +public class CommandConfigInfo implements Cloneable { + + public long delay; + public long duration; + public String command; + public Map payload; + public long timestamp; + + public Uuid uuid; + + @Override + public CommandConfigInfo clone() { + try { + CommandConfigInfo ret = (CommandConfigInfo) super.clone(); + if (payload != null) { + ret.payload = new HashMap<>(this.payload); + } + return ret; + } catch (CloneNotSupportedException e) { + throw new IllegalStateException("Cannot clone ", e); + } + } + + @Override + public String toString() { + return String.format("CommandConfigInfo [delay=%s, duration=%s, command=%s, payload=%s, timestamp=%s, uuid=%s]", + delay, duration, command, payload, timestamp, uuid); + } + +} \ No newline at end of file