TW-19 - more fixes to enable proper AP display in the KDC portal

This commit is contained in:
DTop
2020-02-11 18:48:24 -05:00
parent 472ab43de2
commit 285973f4ec
9 changed files with 262 additions and 20 deletions

View File

@@ -1,12 +1,13 @@
package ai.connectus.opensync.external.integration;
import ai.connectus.opensync.external.integration.models.ConnectNodeInfo;
import ai.connectus.opensync.external.integration.models.OpensyncAPConfig;
import sts.PlumeStats.Report;
import traffic.NetworkMetadata.FlowReport;
import wc.stats.IpDnsTelemetry.WCStatsReport;
public interface OpensyncExternalIntegrationInterface {
void apConnected(String apId);
void apConnected(String apId, ConnectNodeInfo connectNodeInfo);
void apDisconnected(String apId);
OpensyncAPConfig getApConfig(String apId);
void processMqttMessage(String topic, Report report);

View File

@@ -1,4 +1,4 @@
package ai.connectus.opensync.ovsdb.dao.models;
package ai.connectus.opensync.external.integration.models;
import java.util.HashMap;
import java.util.Map;
@@ -9,6 +9,12 @@ public class ConnectNodeInfo implements Cloneable{
public String managerAddr;
public String skuNumber;
public String serialNumber;
public String macAddress;
public String ipV4Address;
public String platformVersion;
public String firmwareVersion;
public String model;
@Override
public ConnectNodeInfo clone() {
@@ -23,11 +29,14 @@ public class ConnectNodeInfo implements Cloneable{
}
}
@Override
public String toString() {
return String.format(
"ConnectNodeInfo [mqttSettings=%s, redirectorAddr=%s, managerAddr=%s, skuNumber=%s, serialNumber=%s]",
mqttSettings, redirectorAddr, managerAddr, skuNumber, serialNumber);
"ConnectNodeInfo [mqttSettings=%s, redirectorAddr=%s, managerAddr=%s, skuNumber=%s, serialNumber=%s, "
+ "macAddress=%s, ipV4Address=%s, platformVersion=%s, firmwareVersion=%s, model=%s]",
mqttSettings, redirectorAddr, managerAddr, skuNumber, serialNumber, macAddress, ipV4Address,
platformVersion, firmwareVersion, model);
}
}

View File

@@ -45,6 +45,11 @@
<artifactId>equipment-metrics-collector-service-remote</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.whizcontrol</groupId>
<artifactId>equipment-status-and-alarm-collector-service-remote</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- KDC models -->
<dependency>

View File

@@ -1,6 +1,8 @@
package ai.connectus.opensync.external.integration;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -38,12 +40,20 @@ import com.whizcontrol.equipmentandnetworkconfig.models.SsidConfiguration.Applie
import com.whizcontrol.equipmentandnetworkconfig.models.SsidConfiguration.SecureMode;
import com.whizcontrol.equipmentandnetworkconfig.models.StateSetting;
import com.whizcontrol.equipmentandnetworkmanagement.EquipmentAndNetworkManagementInterface;
import com.whizcontrol.equipmentandnetworkstatus.models.EquipmentProtocolState;
import com.whizcontrol.equipmentandnetworkstatus.models.StatusCode;
import com.whizcontrol.equipmentandnetworkstatus.models.equipment.CustomerEquipmentStatusRecord;
import com.whizcontrol.equipmentandnetworkstatus.models.equipment.EquipmentAdminStatusData;
import com.whizcontrol.equipmentandnetworkstatus.models.equipment.EquipmentLANStatusData;
import com.whizcontrol.equipmentandnetworkstatus.models.equipment.EquipmentProtocolStatusData;
import com.whizcontrol.equipmentandnetworkstatus.models.equipment.VLANStatusData;
import com.whizcontrol.equipmentconfigurationmanager.EquipmentConfigurationManagerInterface;
import com.whizcontrol.equipmentconfigurationmanager.models.ResolvedEquipmentConfiguration;
import com.whizcontrol.equipmentinventory.models.CustomerEquipment;
import com.whizcontrol.equipmentmetricscollector.EquipmentMetricsCollectorInterface;
import com.whizcontrol.equipmentrouting.EquipmentRoutingInterface;
import com.whizcontrol.equipmentroutinginfo.models.EquipmentRoutingRecord;
import com.whizcontrol.equipmentstatusandalarmcollector.EquipmentStatusAndAlarmCollectorInterface;
import com.whizcontrol.orderandsubscriptionmanagement.OrderAndSubscriptionManagementInterface;
import com.whizcontrol.servicemetrics.models.APDemoMetric;
import com.whizcontrol.servicemetrics.models.ApClientMetrics;
@@ -55,9 +65,11 @@ import com.whizcontrol.servicemetrics.models.NeighbourScanReports;
import com.whizcontrol.servicemetrics.models.SingleMetricRecord;
import ai.connectus.opensync.external.integration.controller.OpensyncKDCGatewayController;
import ai.connectus.opensync.external.integration.models.ConnectNodeInfo;
import ai.connectus.opensync.external.integration.models.OpensyncAPConfig;
import ai.connectus.opensync.external.integration.models.OpensyncAPRadioConfig;
import ai.connectus.opensync.external.integration.models.OpensyncAPSsidConfig;
import sts.PlumeStats.Client;
import sts.PlumeStats.ClientReport;
import sts.PlumeStats.Device;
@@ -87,6 +99,9 @@ public class OpensyncExternalIntegrationKDC implements OpensyncExternalIntegrati
@Autowired
private EquipmentMetricsCollectorInterface equipmentMetricsCollectorInterface;
@Autowired
private EquipmentStatusAndAlarmCollectorInterface equipmentStatusInterface;
/**
* Equipment routing provide the qrCode to CE gateway mapping
*/
@@ -117,7 +132,7 @@ public class OpensyncExternalIntegrationKDC implements OpensyncExternalIntegrati
kdcEquipmentRecordCache = cacheManagerShortLived.getCache("KDC_equipment_record_cache");
}
public void apConnected(String apId) {
public void apConnected(String apId, ConnectNodeInfo connectNodeInfo) {
LOG.info("AP {} got connected to the gateway", apId);
try {
@@ -182,11 +197,28 @@ public class OpensyncExternalIntegrationKDC implements OpensyncExternalIntegrati
equipmentElementConfiguration = eqNetworkManagementInterface
.createEquipmentElementConfiguration(equipmentElementConfiguration);
// Establish admin status for the new equipment.
try {
CustomerEquipmentStatusRecord statusRecord = new CustomerEquipmentStatusRecord();
statusRecord.setCustomerId(ce.getCustomerId());
statusRecord.setEquipmentId(ce.getId());
EquipmentAdminStatusData statusData = new EquipmentAdminStatusData();
statusData.setStatusCode(StatusCode.normal);
statusData.setCustomerLevelStatusCode(StatusCode.normal);
statusRecord.setStatusData(statusData);
// Update the equipment status
equipmentStatusInterface.updateEquipmentAdminStatus(statusRecord);
} catch (Exception e) {
//do nothing
}
//cache newly created AP
kdcEquipmentRecordCache.put(apId, ce);
}
//register equipment routing record
EquipmentRoutingRecord equipmentRoutingRecord = new EquipmentRoutingRecord();
equipmentRoutingRecord.setGatewayRecordId(kdcGwController.getRegisteredGwId());
equipmentRoutingRecord.setCustomerId(ce.getCustomerId());
@@ -197,6 +229,85 @@ public class OpensyncExternalIntegrationKDC implements OpensyncExternalIntegrati
ovsdbSession.setEquipmentId(ce.getId());
ovsdbSession.setCustomerId(ce.getCustomerId());
//update equipment status
// Establish admin status for the connected equipment.
CustomerEquipmentStatusRecord statusRecord = equipmentStatusInterface.getEquipmentAdminStatusByEquipmentId(ce.getCustomerId(), ce.getId(), false);
if(statusRecord==null) {
statusRecord = new CustomerEquipmentStatusRecord();
statusRecord.setCustomerId(ce.getCustomerId());
statusRecord.setEquipmentId(ce.getId());
EquipmentAdminStatusData statusData = new EquipmentAdminStatusData();
statusRecord.setStatusData(statusData);
}
((EquipmentAdminStatusData)statusRecord.getStatusData()).setStatusCode(StatusCode.normal);
((EquipmentAdminStatusData)statusRecord.getStatusData()).setCustomerLevelStatusCode(StatusCode.normal);
// Update the equipment status
equipmentStatusInterface.updateEquipmentAdminStatus(statusRecord);
//update LAN status - nothing to do here for now
statusRecord = equipmentStatusInterface.getEquipmentLANStatusByEquipmentId(ce.getCustomerId(), ce.getId(), false);
if(statusRecord==null) {
statusRecord = new CustomerEquipmentStatusRecord();
statusRecord.setCustomerId(ce.getCustomerId());
statusRecord.setEquipmentId(ce.getId());
EquipmentLANStatusData statusData = new EquipmentLANStatusData();
statusRecord.setStatusData(statusData);
}
Map<Integer, VLANStatusData> vlanStatusDataMap = new HashMap<>();
((EquipmentLANStatusData)statusRecord.getStatusData()).setVlanStatusDataMap(vlanStatusDataMap );
equipmentStatusInterface.updateEquipmentLANStatus(statusRecord);
//update protocol status
statusRecord = equipmentStatusInterface.getEquipmentProtocolStatusByEquipmentId(ce.getCustomerId(), ce.getId(), false);
if(statusRecord==null) {
statusRecord = new CustomerEquipmentStatusRecord();
statusRecord.setCustomerId(ce.getCustomerId());
statusRecord.setEquipmentId(ce.getId());
EquipmentProtocolStatusData statusData = new EquipmentProtocolStatusData();
statusRecord.setStatusData(statusData);
}
EquipmentProtocolStatusData protocolStatusData = ((EquipmentProtocolStatusData)statusRecord.getStatusData());
protocolStatusData.setPoweredOn(true);
protocolStatusData.setCloudProtocolVersion("1100");
protocolStatusData.setProtocolState(EquipmentProtocolState.ready);
protocolStatusData.setBandPlan("FCC");
protocolStatusData.setBaseMacAddress(MacAddress.valueOf(connectNodeInfo.macAddress));
protocolStatusData.setCloudCfgDataVersion(42L);
protocolStatusData.setReportedCfgDataVersion(42L);
protocolStatusData.setCountryCode("CA");
protocolStatusData.setReportedCC(CountryCode.ca);
protocolStatusData.setReportedHwVersion(connectNodeInfo.platformVersion);
protocolStatusData.setReportedSwVersion(connectNodeInfo.firmwareVersion);
protocolStatusData.setReportedSwAltVersion(connectNodeInfo.firmwareVersion);
protocolStatusData.setReportedIpV4Addr(InetAddress.getByName(connectNodeInfo.ipV4Address));
if(connectNodeInfo.macAddress!=null && MacAddress.valueOf(connectNodeInfo.macAddress)!=null) {
protocolStatusData.setReportedMacAddr(MacAddress.valueOf(connectNodeInfo.macAddress).getAddress());
}
protocolStatusData.setReportedSku(connectNodeInfo.skuNumber);
protocolStatusData.setSerialNumber(connectNodeInfo.serialNumber);
protocolStatusData.setSystemName(connectNodeInfo.model);
equipmentStatusInterface.updateEquipmentProtocolStatus(statusRecord);
//TODO: continue from here --->>>
//TODO: equipmentStatusInterface.updateEquipmentFirmwareStatus(statusRecord);
//TODO: equipmentStatusInterface.updateEquipmentNeighbouringStatusRecord(record);
//TODO: equipmentStatusInterface.updateEquipmentPeerStatus(statusRecord);
//TODO: equipmentStatusInterface.updateNetworkAdminStatus(networkAdminStatusRecord);
//TODO: equipmentStatusInterface.updateNetworkAggregateStatus(networkAggregateStatusRecord);
}catch(Exception e) {
LOG.error("Exception when registering ap routing {}", apId, e);
}

View File

@@ -11,6 +11,7 @@ import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import ai.connectus.opensync.external.integration.OpensyncExternalIntegrationInterface;
import ai.connectus.opensync.external.integration.models.ConnectNodeInfo;
import ai.connectus.opensync.external.integration.models.OpensyncAPConfig;
import sts.PlumeStats.Report;
import traffic.NetworkMetadata.FlowReport;
@@ -30,7 +31,7 @@ public class OpensyncExternalIntegrationSimple implements OpensyncExternalIntegr
LOG.info("Using Static integration");
}
public void apConnected(String apId) {
public void apConnected(String apId, ConnectNodeInfo connectNodeInfo) {
LOG.info("AP {} got connected to the gateway", apId);
}

View File

@@ -18,9 +18,9 @@ import com.vmware.ovsdb.service.OvsdbPassiveConnectionListener;
import ai.connectus.opensync.external.integration.OpensyncExternalIntegrationInterface;
import ai.connectus.opensync.external.integration.OvsdbSession;
import ai.connectus.opensync.external.integration.OvsdbSessionMapInterface;
import ai.connectus.opensync.external.integration.models.ConnectNodeInfo;
import ai.connectus.opensync.external.integration.models.OpensyncAPConfig;
import ai.connectus.opensync.ovsdb.dao.OvsdbDao;
import ai.connectus.opensync.ovsdb.dao.models.ConnectNodeInfo;
import ai.connectus.opensync.util.SslUtil;
import io.netty.handler.ssl.SslContext;
@@ -76,7 +76,7 @@ public class ConnectusOvsdbClient {
//In Plume's environment clientCn is not unique that's why we are augmenting it with the serialNumber and using it as a key (equivalent of KDC unique qrCode)
String key = clientCn + "_" + connectNodeInfo.serialNumber;
ConnectusOvsdbClient.this.ovsdbSessionMapInterface.newSession(key, ovsdbClient);
extIntegrationInterface.apConnected(key);
extIntegrationInterface.apConnected(key, connectNodeInfo);
//push configuration to AP
connectNodeInfo = processConnectRequest(ovsdbClient, clientCn, connectNodeInfo);
@@ -111,8 +111,8 @@ public class ConnectusOvsdbClient {
String key = ConnectusOvsdbClient.this.ovsdbSessionMapInterface.lookupClientId(ovsdbClient);
if(key!=null) {
ConnectusOvsdbClient.this.ovsdbSessionMapInterface.removeSession(key);
extIntegrationInterface.apDisconnected(key);
ConnectusOvsdbClient.this.ovsdbSessionMapInterface.removeSession(key);
}
ovsdbClient.shutdown();
@@ -142,7 +142,7 @@ public class ConnectusOvsdbClient {
ovsdbDao.updateDeviceStatsReportingInterval(ovsdbClient, collectionIntervalSecDeviceStats);
}
ovsdbDao.removeOnboardingSsids(ovsdbClient);
ovsdbDao.removeAllSsids(ovsdbClient);
if(opensyncAPConfig!=null) {
ovsdbDao.configureWifiRadios(ovsdbClient, opensyncAPConfig.getRadioConfig());

View File

@@ -33,10 +33,10 @@ import com.vmware.ovsdb.protocol.operation.result.SelectResult;
import com.vmware.ovsdb.service.OvsdbClient;
import com.whizcontrol.core.model.equipment.RadioType;
import ai.connectus.opensync.external.integration.models.ConnectNodeInfo;
import ai.connectus.opensync.external.integration.models.OpensyncAPRadioConfig;
import ai.connectus.opensync.external.integration.models.OpensyncAPSsidConfig;
import ai.connectus.opensync.ovsdb.dao.models.BridgeInfo;
import ai.connectus.opensync.ovsdb.dao.models.ConnectNodeInfo;
import ai.connectus.opensync.ovsdb.dao.models.InterfaceInfo;
import ai.connectus.opensync.ovsdb.dao.models.PortInfo;
import ai.connectus.opensync.ovsdb.dao.models.WifiInetConfigInfo;
@@ -73,6 +73,7 @@ public class OvsdbDao {
public static final String wifiRadioConfigDbTable = "Wifi_Radio_Config";
public static final String wifiVifConfigDbTable = "Wifi_VIF_Config";
public static final String wifiInetConfigDbTable = "Wifi_Inet_Config";
public static final String wifiInetStateDbTable = "Wifi_Inet_State";
@@ -92,6 +93,10 @@ public class OvsdbDao {
columns.add("manager_addr");
columns.add("sku_number");
columns.add("serial_number");
columns.add("model");
columns.add("firmware_version");
columns.add("platform_version");
operations.add(new Select(awlanNodeDbTable, conditions , columns ));
CompletableFuture<OperationResult[]> fResult = ovsdbClient.transact(ovsdbName, operations);
@@ -114,8 +119,21 @@ public class OvsdbDao {
ret.redirectorAddr = (row!=null)?row.getStringColumn("redirector_addr"):null;
ret.managerAddr = (row!=null)?row.getStringColumn("manager_addr"):null;
ret.platformVersion = (row!=null)?row.getStringColumn("platform_version"):null;
ret.firmwareVersion = (row!=null)?row.getStringColumn("firmware_version"):null;
ret.skuNumber = getSingleValueFromSet(row, "sku_number");
ret.serialNumber = getSingleValueFromSet(row, "serial_number");
ret.serialNumber = getSingleValueFromSet(row, "serial_number");
ret.model = getSingleValueFromSet(row, "model");
//now populate macAddress, ipV4Address from Wifi_Inet_State
//first look them up for if_name = br-wan
fillInIpAddressAndMac(ovsdbClient, ret, "br-wan");
if(ret.ipV4Address == null || ret.macAddress==null) {
//when not found - look them up for if_name = br-lan
fillInIpAddressAndMac(ovsdbClient, ret, "br-lan");
}
} catch(OvsdbClientException | TimeoutException | ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
@@ -124,6 +142,45 @@ public class OvsdbDao {
return ret;
}
public void fillInIpAddressAndMac(OvsdbClient ovsdbClient, ConnectNodeInfo connectNodeInfo, String ifName) {
try {
List<Operation> operations = new ArrayList<>();
List<Condition> conditions = new ArrayList<>();
List<String> columns = new ArrayList<>();
//populate macAddress, ipV4Address from Wifi_Inet_State
columns.add("inet_addr");
columns.add("hwaddr");
conditions.add(new Condition("if_name", Function.EQUALS, new Atom<>(ifName) ));
operations.add(new Select(wifiInetStateDbTable, conditions , columns ));
CompletableFuture<OperationResult[]> fResult = ovsdbClient.transact(ovsdbName, operations);
OperationResult[] result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS);
if(LOG.isDebugEnabled()) {
LOG.debug("Select from {}:", wifiInetStateDbTable);
for(OperationResult res : result) {
LOG.debug("Op Result {}", res);
}
}
Row row = null;
if (result != null && result.length > 0 && !((SelectResult) result[0]).getRows().isEmpty()) {
row = ((SelectResult)result[0]).getRows().iterator().next();
connectNodeInfo.ipV4Address = getSingleValueFromSet(row, "inet_addr");
connectNodeInfo.macAddress = row.getStringColumn("hwaddr");
}
} catch(OvsdbClientException | TimeoutException | ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
}
public ConnectNodeInfo updateConnectNodeInfoOnConnect(OvsdbClient ovsdbClient, String clientCn, ConnectNodeInfo incomingConnectNodeInfo) {
ConnectNodeInfo ret = incomingConnectNodeInfo.clone();
@@ -367,11 +424,21 @@ public class OvsdbDao {
InterfaceInfo interfaceInfo = new InterfaceInfo();
interfaceInfo.name = row.getStringColumn("name");
interfaceInfo.uuid = row.getUuidColumn("_uuid");
interfaceInfo.ofport = row.getIntegerColumn("ofport").intValue();
interfaceInfo.mtu = row.getIntegerColumn("mtu").intValue();
interfaceInfo.ifIndex = row.getIntegerColumn("ifindex").intValue();
interfaceInfo.linkState = row.getStringColumn("link_state");
interfaceInfo.adminState = row.getStringColumn("admin_state");
Long tmp = getSingleValueFromSet(row, "ofport");
interfaceInfo.ofport = tmp!=null?tmp.intValue():0;
tmp = getSingleValueFromSet(row, "mtu");
interfaceInfo.mtu = tmp!=null?tmp.intValue():0;
tmp = getSingleValueFromSet(row, "ifindex");
interfaceInfo.ifIndex = tmp!=null?tmp.intValue():0;
String tmpStr = getSingleValueFromSet(row, "link_state");
interfaceInfo.linkState = tmpStr!=null?tmpStr:"";
tmpStr = getSingleValueFromSet(row, "admin_state");
interfaceInfo.adminState = tmpStr!=null?tmpStr:"";
ret.put(interfaceInfo.name, interfaceInfo);
}
@@ -904,6 +971,54 @@ public class OvsdbDao {
}
public void removeAllSsids(OvsdbClient ovsdbClient) {
try {
List<Operation> operations = new ArrayList<>();
operations.add(new Delete(wifiVifConfigDbTable));
CompletableFuture<OperationResult[]> fResult = ovsdbClient.transact(ovsdbName, operations);
OperationResult[] result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS);
if(LOG.isDebugEnabled()) {
LOG.debug("Removed all existing SSIDs from {}:", wifiVifConfigDbTable);
for(OperationResult res : result) {
LOG.debug("Op Result {}", res);
}
}
//Now clean up references in the vif_configs columns
operations = new ArrayList<>();
Map<String, Value> updateColumns = new HashMap<>();
Set<Uuid> vifConfigsSet = new HashSet<>();
com.vmware.ovsdb.protocol.operation.notation.Set vifConfigs = com.vmware.ovsdb.protocol.operation.notation.Set.of(vifConfigsSet);
updateColumns.put("vif_configs", vifConfigs );
Row row = new Row(updateColumns);
operations.add(new Update(wifiRadioConfigDbTable, row ));
fResult = ovsdbClient.transact(ovsdbName, operations);
result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS);
if(LOG.isDebugEnabled()) {
LOG.debug("Updated WifiRadioConfig ");
for(OperationResult res : result) {
LOG.debug("Op Result {}", res);
}
}
LOG.info("Removed all ssids");
} catch(OvsdbClientException | TimeoutException | ExecutionException | InterruptedException e) {
LOG.error("Error in removeAllSsids", e);
throw new RuntimeException(e);
}
}
public void configureWifiRadios(OvsdbClient ovsdbClient, OpensyncAPRadioConfig opensyncAPRadioConfig) {
Map<String,WifiRadioConfigInfo> provisionedWifiRadios = getProvisionedWifiRadioConfigs(ovsdbClient);
LOG.debug("Existing WifiRadioConfigs: {}", provisionedWifiRadios.keySet());

View File

@@ -10,7 +10,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/openjdk-13.0.2"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/OpenJDK 13.0.2"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="ai.connectus.opensync.experiment.OpenSyncProcess"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="opensync_gateway_kdc_process"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/>

View File

@@ -10,7 +10,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/openjdk-13.0.2"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/OpenJDK 13.0.2"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="ai.connectus.opensync.experiment.OpenSyncProcess"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="opensync_gateway_static_process"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/>