implemented equipment gateway service to deliver commands to the APs

This commit is contained in:
Dmitry Toptygin
2020-06-09 15:44:30 -04:00
parent e7cbaf52a6
commit fa25757a05
27 changed files with 1459 additions and 0 deletions

View File

@@ -170,6 +170,11 @@
<module>../manufacturer-service-local</module>
<module>../manufacturer-service-remote</module>
<module>../equipment-gateway-models</module>
<module>../equipment-gateway-service-interface</module>
<module>../equipment-gateway-service-local</module>
<module>../equipment-gateway-service-remote</module>
<module>../provisioning-sp</module>
<module>../single-process-streams</module>

View File

@@ -0,0 +1,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.telecominfraproject.wlan</groupId>
<artifactId>tip-wlan-cloud-root-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>equipment-gateway-models</artifactId>
<name>equipment-gateway-models</name>
<description>Data structures that define equipment-gateway-related objects.</description>
<dependencies>
<dependency>
<groupId>com.telecominfraproject.wlan</groupId>
<artifactId>base-models</artifactId>
<version>${tip-wlan-cloud.release.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,161 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
import com.telecominfraproject.wlan.core.model.role.PortalUserRole;
public class CEGWBaseCommand extends BaseJsonModel {
private static final long serialVersionUID = 1369966637498613810L;
/**
* Command Type
*/
private CEGWCommandType commandType;
/**
* Equipment Identifier
*/
private long equipmentId;
/**
* Equipment inventory Id
*/
private String inventoryId;
/**
* Portal user name
*/
private String userName;
/**
* Portal user role
*/
private PortalUserRole userRole;
/**
* Only used to JSON decoding
*/
protected CEGWBaseCommand() {
this.commandType = CEGWCommandType.Unknown;
}
protected CEGWBaseCommand(CEGWCommandType commandType, String inventoryId, long equipmentId) {
this(commandType, inventoryId, equipmentId, null, null);
}
protected CEGWBaseCommand(CEGWCommandType commandType, String inventoryId, long equipmentId,
PortalUserRole userRole, String userName) {
this.commandType = commandType;
this.inventoryId = inventoryId;
this.equipmentId = equipmentId;
this.userRole = userRole;
this.userName = userName;
}
@Override
public CEGWBaseCommand clone() {
return (CEGWBaseCommand) super.clone();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof CEGWBaseCommand)) {
return false;
}
CEGWBaseCommand other = (CEGWBaseCommand) obj;
if (this.commandType != other.commandType) {
return false;
}
if (this.equipmentId != other.equipmentId) {
return false;
}
if (this.inventoryId == null) {
if (other.inventoryId != null) {
return false;
}
} else if (!this.inventoryId.equals(other.inventoryId)) {
return false;
}
if (this.userRole != other.userRole) {
return false;
}
if (this.userName == null) {
if (other.userName != null) {
return false;
}
} else if (!this.userName.equals(other.userName)) {
return false;
}
return true;
}
public CEGWCommandType getCommandType() {
return commandType;
}
public long getEquipmentId() {
return this.equipmentId;
}
public String getInventoryId() {
return inventoryId;
}
public String getUsername() {
return userName;
}
public PortalUserRole getUserRole() {
return userRole;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.commandType == null) ? 0 : this.commandType.hashCode());
result = prime * result + (int) (this.equipmentId ^ (this.equipmentId >>> 32));
result = prime * result + ((this.inventoryId == null) ? 0 : this.inventoryId.hashCode());
result = prime * result + ((this.userRole == null) ? 0 : this.userRole.hashCode());
result = prime * result + ((this.userName == null) ? 0 : this.userName.hashCode());
return result;
}
@Override
public boolean hasUnsupportedValue() {
if (super.hasUnsupportedValue()) {
return true;
}
if (CEGWCommandType.isUnsupported(commandType) || PortalUserRole.isUnsupported(userRole)) {
return true;
}
return false;
}
public void setCommandType(CEGWCommandType commandType) {
this.commandType = commandType;
}
public void setEquipmentId(long equipmentId) {
this.equipmentId = equipmentId;
}
public void setInventoryId(String inventoryId) {
this.inventoryId = inventoryId;
}
public void setUsername(String portalUsername) {
this.userName = portalUsername;
}
public void setUserRole(PortalUserRole portalRole) {
this.userRole = portalRole;
}
}

View File

@@ -0,0 +1,82 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
import com.telecominfraproject.wlan.core.model.equipment.LEDColour;
public class CEGWBlinkRequest extends EquipmentCommand {
private static final long serialVersionUID = 3464950479960821571L;
private int numCycles;
private int colour1DurationMs;
private int colour2DurationMs;
private LEDColour colour1;
private LEDColour colour2;
/**
* Constructor
*
* @param inventoryId
* @param equipmentId
*/
public CEGWBlinkRequest(String inventoryId, long equipmentId) {
super(CEGWCommandType.BlinkRequest, inventoryId, equipmentId);
}
/**
* Constructor used by JSON
*/
public CEGWBlinkRequest() {
super(CEGWCommandType.BlinkRequest, null, 0);
}
public int getNumCycles() {
return numCycles;
}
public void setNumCycles(int numCycles) {
this.numCycles = numCycles;
}
public int getColour1DurationMs() {
return colour1DurationMs;
}
public void setColour1DurationMs(int colourDurationMs) {
this.colour1DurationMs = colourDurationMs;
}
public int getColour2DurationMs() {
return colour2DurationMs;
}
public void setColour2DurationMs(int colourDurationMs) {
this.colour2DurationMs = colourDurationMs;
}
public LEDColour getColour1() {
return colour1;
}
public void setColour1(LEDColour colour1) {
this.colour1 = colour1;
}
public LEDColour getColour2() {
return colour2;
}
public void setColour2(LEDColour colour2) {
this.colour2 = colour2;
}
@Override
public boolean hasUnsupportedValue() {
if (super.hasUnsupportedValue()) {
return true;
}
if (LEDColour.isUnsupported(colour1) || LEDColour.isUnsupported(colour2)) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,24 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
public class CEGWCloseSessionRequest extends CEGatewayCommand {
private static final long serialVersionUID = -263965970528271895L;
public CEGWCloseSessionRequest(String inventoryId, long equipmentId) {
super(CEGWCommandType.CloseSessionRequest, inventoryId, equipmentId);
}
/**
* Constructor used by JSON
*/
public CEGWCloseSessionRequest() {
super(CEGWCommandType.CloseSessionRequest, null, 0);
}
@Override
public CEGWCloseSessionRequest clone() {
return (CEGWCloseSessionRequest) super.clone();
}
}

View File

@@ -0,0 +1,30 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
public enum CEGWCommandResultCode {
/**
* Successfully delivered to CE
*/
Success,
/**
* No route to CE.
*/
NoRouteToCE,
/**
* Failed to deliver the message to CE.
*/
FailedToSend,
/**
* Timed out waiting for CE to response. CEGW will not return this code because
* communication is asynchronous.
*/
TimedOut,
/**
* Failure reported by customer equipment CEGW will not return this code because
* communication is asynchronous.
*/
FailedOnCE,
/**
* Command code not supported
*/
UnsupportedCommand;
}

View File

@@ -0,0 +1,91 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
import com.fasterxml.jackson.annotation.JsonCreator;
public enum CEGWCommandType {
/**
* Notification to CE for configuration change
*/
Unknown, ConfigChangeNotification, FirmwareDownloadRequest, StartDebugEngine, StopDebugEngine, FirmwareFlashRequest,
RebootRequest, BlinkRequest, CloseSessionRequest, NeighbourhoodReport, ClientDeauthRequest, CellSizeRequest,
NewChannelRequest, ReportCurrentAPCRequest, FileUpdateRequest, InterferenceThresholdUpdateRequest,
BestApConfigurationUpdateRequest,
/**
* Will tell the AP to monitor these macs filters for hardwired traffic (aka:
* Rogue AP)
*/
BSSIDToMacMonitoringRequest,
// Will tell the AP to dynamically change channels
ChannelChangeAnnouncementRequest,
/**
* Start packet capture into file
*/
StartPacketFileCapture,
/**
* Stop packet capture
*/
StopPacketCapture,
/**
* Check for routing record
*/
CheckRouting, ReportCurrentVLANRequest,
/**
* Log file upload
*/
UploadLogFile,
/**
* For toggle PoE port on switch.
*/
TogglePoERequest,
/**
* Reset radio
*/
RadioReset,
/**
* Clear scan table
*/
ClearScanTable,
/**
* For commands related to wds link of Mesh.
*/
WdsRequest,
UNSUPPORTED;
@JsonCreator
public static CEGWCommandType getByName(String value) {
return deserializEnum(value, CEGWCommandType.class, UNSUPPORTED);
}
public static boolean isUnsupported(Object value) {
return UNSUPPORTED.equals(value);
}
/**
* Deserialize enumeration with default value when it's unknown.
*
* @param jsonValue
* @param enumType
* @param defaultValue
* @return decoded value
*/
public static <E extends Enum<E>> E deserializEnum(String jsonValue, Class<E> enumType, E defaultValue) {
if (null == jsonValue) {
return null;
}
try {
E result = E.valueOf(enumType, jsonValue);
return result;
} catch (IllegalArgumentException e) {
return defaultValue;
}
}
}

View File

@@ -0,0 +1,24 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
public class CEGWConfigChangeNotification extends EquipmentCommand {
private static final long serialVersionUID = 4401284478686864193L;
/**
* Constructor
*
* @param inventoryId
* @param equipmentId
*/
public CEGWConfigChangeNotification(String inventoryId, long equipmentId) {
super(CEGWCommandType.ConfigChangeNotification, inventoryId, equipmentId);
}
/**
* Constructor used by JSON
*/
protected CEGWConfigChangeNotification() {
super(CEGWCommandType.ConfigChangeNotification, null, 0);
}
}

View File

@@ -0,0 +1,12 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
public class CEGWRouteCheck extends EquipmentCommand {
private static final long serialVersionUID = 8778460868381668813L;
public Object getRoutingId() {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -0,0 +1,60 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
public class CEGWStartDebugEngine extends EquipmentCommand {
private static final long serialVersionUID = -6768986657458247552L;
/**
* Gateway hostname
*/
private String gatewayHostname;
/**
* Gateway port
*/
private Integer gatewayPort;
/**
* Constructor
*
* @param inventoryId
* @param equipmentId
* @param gatewayHostname
* @param gatewayPort
*/
public CEGWStartDebugEngine(String inventoryId, long equipmentId, String gatewayHostname, Integer gatewayPort) {
super(CEGWCommandType.StartDebugEngine, inventoryId, equipmentId);
this.setGatewayHostname(gatewayHostname);
this.setGatewayPort(gatewayPort);
}
/**
* Constructor used by JSON
*/
public CEGWStartDebugEngine() {
super(CEGWCommandType.StartDebugEngine, null, 0);
}
public String getGatewayHostname() {
return gatewayHostname;
}
public void setGatewayHostname(String gatewayHostname) {
this.gatewayHostname = gatewayHostname;
}
public Integer getGatewayPort() {
return gatewayPort;
}
public void setGatewayPort(Integer gatewayPort) {
this.gatewayPort = gatewayPort;
}
@Override
public boolean hasUnsupportedValue() {
if (super.hasUnsupportedValue()) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,13 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
public class CEGatewayCommand extends CEGWBaseCommand {
private static final long serialVersionUID = 4545056375390115226L;
protected CEGatewayCommand() {
}
protected CEGatewayCommand(CEGWCommandType commandType, String inventoryId, long equipmentId) {
super(commandType, inventoryId, equipmentId);
}
}

View File

@@ -0,0 +1,21 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
import com.telecominfraproject.wlan.core.model.role.PortalUserRole;
public class EquipmentCommand extends CEGWBaseCommand {
private static final long serialVersionUID = -1981617366942595011L;
protected EquipmentCommand() {
}
protected EquipmentCommand(CEGWCommandType commandType, String inventoryId, long equipmentId) {
this(commandType, inventoryId, equipmentId, null, null);
}
protected EquipmentCommand(CEGWCommandType commandType, String inventoryId, long equipmentId,
PortalUserRole userRole, final String userName) {
super(commandType, inventoryId, equipmentId, userRole, userName);
}
}

View File

@@ -0,0 +1,83 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
public class EquipmentCommandResponse extends BaseJsonModel {
private static final long serialVersionUID = 5977811650122183402L;
private CEGWCommandResultCode resultCode;
/**
* Detail for the result
*/
private String resultDetail;
private CEGWBaseCommand command;
private String gatewayHost;
private int gatewayPort;
/**
* @param resultCode
* @param resultDetail
* @param command - equipment command for which this response is generated
*/
public EquipmentCommandResponse(CEGWCommandResultCode resultCode, String resultDetail, CEGWBaseCommand command, String gatewayHost, int gatewayPort) {
this.resultCode = resultCode;
this.resultDetail = resultDetail;
this.command = command;
this.gatewayHost = gatewayHost;
this.gatewayPort = gatewayPort;
}
public EquipmentCommandResponse() {
}
public CEGWCommandResultCode getResultCode() {
return resultCode;
}
@Override
public EquipmentCommandResponse clone() {
return (EquipmentCommandResponse) super.clone();
}
public String getResultDetail() {
return resultDetail;
}
public void setResultDetail(String resultDetail) {
this.resultDetail = resultDetail;
}
public CEGWBaseCommand getCommand() {
return command;
}
public void setCommand(CEGWBaseCommand command) {
this.command = command;
}
public void setResultCode(CEGWCommandResultCode resultCode) {
this.resultCode = resultCode;
}
public String getGatewayHost() {
return gatewayHost;
}
public void setGatewayHost(String gatewayHost) {
this.gatewayHost = gatewayHost;
}
public int getGatewayPort() {
return gatewayPort;
}
public void setGatewayPort(int gatewayPort) {
this.gatewayPort = gatewayPort;
}
}

View File

@@ -0,0 +1,35 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
import java.util.HashMap;
import java.util.Map;
import com.telecominfraproject.wlan.core.model.equipment.RadioType;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
public class GatewayDefaults extends BaseJsonModel {
private static final long serialVersionUID = 1781633756875649610L;
private Map<RadioType, GatewayRadioDefaults> defaults = new HashMap<RadioType, GatewayRadioDefaults>();
private Boolean default11w;
public GatewayDefaults() {
}
public Map<RadioType, GatewayRadioDefaults> getDefaults() {
return defaults;
}
public void setDefaults(Map<RadioType, GatewayRadioDefaults> defaults) {
this.defaults = defaults;
}
public Boolean getDefault11w() {
return default11w;
}
public void setDefault11w(Boolean default11w) {
this.default11w = default11w;
}
}

View File

@@ -0,0 +1,40 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
public class GatewayRadioDefaults extends BaseJsonModel {
private static final long serialVersionUID = 8302320644769648937L;
private Boolean default11k;
private Boolean default11v;
private Boolean default11r;
public GatewayRadioDefaults() {
//
}
public Boolean getDefault11k() {
return default11k;
}
public void setDefault11k(Boolean default11k) {
this.default11k = default11k;
}
public Boolean getDefault11v() {
return default11v;
}
public void setDefault11v(Boolean default11v) {
this.default11v = default11v;
}
public Boolean getDefault11r() {
return default11r;
}
public void setDefault11r(Boolean default11r) {
this.default11r = default11r;
}
}

View File

@@ -0,0 +1,157 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
import com.telecominfraproject.wlan.core.model.service.GatewayType;
public class ServiceDeploymentInfo extends BaseJsonModel {
private static final long serialVersionUID = 3075868930647536783L;
/**
* Deployment Identifier
*/
private int deploymentId;
/**
* Type of cloud service
*/
private GatewayType serviceType;
/**
* External host name
*/
private String serviceHostname;
/**
* External port
*/
private int servicePort;
/**
* Last time record is modified
*/
private long lastModifiedTimestamp;
public ServiceDeploymentInfo() {
}
/**
* Constructor
*
* @param serivceType
* @param deploymentId
* @param serviceHostname
* @param servicePort
*/
public ServiceDeploymentInfo(GatewayType serivceType, int deploymentId, String serviceHostname, int servicePort) {
this.serviceType = serivceType;
this.deploymentId = deploymentId;
this.serviceHostname = serviceHostname;
this.servicePort = servicePort;
}
@Override
public ServiceDeploymentInfo clone() {
return (ServiceDeploymentInfo) super.clone();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ServiceDeploymentInfo)) {
return false;
}
ServiceDeploymentInfo other = (ServiceDeploymentInfo) obj;
if (deploymentId != other.deploymentId) {
return false;
}
if (serviceHostname == null) {
if (other.serviceHostname != null) {
return false;
}
} else if (!serviceHostname.equals(other.serviceHostname)) {
return false;
}
if (servicePort != other.servicePort) {
return false;
}
if (serviceType != other.serviceType) {
return false;
}
return true;
}
public int getDeploymentId() {
return deploymentId;
}
public long getLastModifiedTimestamp() {
return lastModifiedTimestamp;
}
public String getServiceHostname() {
return serviceHostname;
}
public int getServicePort() {
return servicePort;
}
public GatewayType getServiceType() {
return serviceType;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + deploymentId;
result = prime * result + ((serviceHostname == null) ? 0 : serviceHostname.hashCode());
result = prime * result + servicePort;
result = prime * result + ((serviceType == null) ? 0 : serviceType.hashCode());
return result;
}
public void setDeploymentId(int deploymentId) {
this.deploymentId = deploymentId;
}
public void setLastModifiedTimestamp(long lastModifiedTimestamp) {
this.lastModifiedTimestamp = lastModifiedTimestamp;
}
public void setServiceHostname(String serviceHostname) {
this.serviceHostname = serviceHostname;
}
public void setServicePort(int servicePort) {
this.servicePort = servicePort;
}
public void setServiceType(GatewayType serviceType) {
this.serviceType = serviceType;
}
@Override
public boolean hasUnsupportedValue() {
if (super.hasUnsupportedValue()) {
return true;
}
if (GatewayType.isUnsupported(serviceType)) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.telecominfraproject.wlan</groupId>
<artifactId>tip-wlan-cloud-root-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>equipment-gateway-service-interface</artifactId>
<name>equipment-gateway-service-interface</name>
<description>Interface definitions for the Equipment Gateway.</description>
<dependencies>
<dependency>
<artifactId>equipment-gateway-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,32 @@
package com.telecominfraproject.wlan.equipmentgateway.service;
import java.util.Arrays;
import java.util.List;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBaseCommand;
import com.telecominfraproject.wlan.equipmentgateway.models.EquipmentCommandResponse;
/**
* @author dtop
* <br>Use this interface to deliver commands to the equipment.
* Each equipment command identifies a target equipment; routing service is used to determine host/port of the gateway that is managing the connected equipment.
* Method sendCommands accepts a batch of commands, each command in there can be for a different equipment, they will be routed accordingly.
*/
public interface EquipmentGatewayServiceInterface {
/**
* Send a batch of commands to the specified equipment gateway
* @param commands - list of commands to send to equipment
* @return list of command responses - one for each command in the incoming batch, in the same order as the incoming commands.
*/
List<EquipmentCommandResponse> sendCommands(List<CEGWBaseCommand> commands);
/**
* Convenience method to send a single command to the equipment gateway
* @param command
* @return command response
*/
default EquipmentCommandResponse sendCommand(CEGWBaseCommand command) {
return sendCommands(Arrays.asList(command)).get(0);
}
}

View File

@@ -0,0 +1,29 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.telecominfraproject.wlan</groupId>
<artifactId>tip-wlan-cloud-root-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>equipment-gateway-service-local</artifactId>
<name>equipment-gateway-service-local</name>
<description>Local client for accessing equipment gateway, uses direct java calls within current JVM process.</description>
<dependencies>
<dependency>
<artifactId>equipment-gateway-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
</dependency>
<dependency>
<artifactId>opensync-ext-cloud</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,23 @@
package com.telecominfraproject.wlan.equipmentgateway.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBaseCommand;
import com.telecominfraproject.wlan.equipmentgateway.models.EquipmentCommandResponse;
import com.telecominfraproject.wlan.opensync.external.integration.controller.OpensyncCloudGatewayController;
@Component
public class EquipmentGatewayServiceLocal implements EquipmentGatewayServiceInterface {
@Autowired OpensyncCloudGatewayController gatewayController;
@Override
public List<EquipmentCommandResponse> sendCommands(List<CEGWBaseCommand> commands) {
return gatewayController.sendCommands(commands);
}
}

View File

@@ -0,0 +1,72 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.telecominfraproject.wlan</groupId>
<artifactId>tip-wlan-cloud-root-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>equipment-gateway-service-remote</artifactId>
<name>equipment-gateway-service-remote</name>
<description>Remote client for accessing equipment gateway, uses REST API calls.</description>
<dependencies>
<dependency>
<artifactId>equipment-gateway-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
</dependency>
<dependency>
<artifactId>routing-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
</dependency>
<dependency>
<artifactId>base-client</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
</dependency>
<!-- Dependencies for the unit tests -->
<dependency>
<artifactId>base-remote-tests</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>routing-service</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>routing-service-remote</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>routing-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>cloud-event-dispatcher-empty</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>${tip-wlan-cloud.release.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,121 @@
package com.telecominfraproject.wlan.equipmentgateway.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import com.telecominfraproject.wlan.core.client.BaseRemoteClient;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBaseCommand;
import com.telecominfraproject.wlan.equipmentgateway.models.EquipmentCommandResponse;
import com.telecominfraproject.wlan.routing.RoutingServiceInterface;
import com.telecominfraproject.wlan.routing.models.EquipmentGatewayRecord;
@Component
public class EquipmentGatewayServiceRemote extends BaseRemoteClient implements EquipmentGatewayServiceInterface {
private static final Logger LOG = LoggerFactory.getLogger(EquipmentGatewayServiceRemote.class);
private static final ParameterizedTypeReference<List<EquipmentCommandResponse>> EquipmentCommandResponse_LIST_CLASS_TOKEN = new ParameterizedTypeReference<List<EquipmentCommandResponse>>() {};
@Autowired RoutingServiceInterface routingServiceInterface;
private String protocol;
@Override
public List<EquipmentCommandResponse> sendCommands(List<CEGWBaseCommand> commands) {
List<EquipmentCommandResponse> ret = new ArrayList<>();
if(commands == null) {
return ret;
}
// split the incoming batch of commands into sub-batches per equipment id
Map<Long, List<CEGWBaseCommand>> equipmentIdToCommandsMap = new HashMap<>();
commands.forEach(c -> {
List<CEGWBaseCommand> cmds = equipmentIdToCommandsMap.get(c.getEquipmentId() );
if(cmds == null) {
cmds = new ArrayList<>();
equipmentIdToCommandsMap.put(c.getEquipmentId(), cmds);
}
cmds.add(c);
});
// for each equipmentId find out EquipmentGatewayRecords (may be multiple)
Map<Long, List<EquipmentGatewayRecord>> equipmentIdToGatewaysMap = new HashMap<>();
equipmentIdToCommandsMap.keySet().forEach(eqId -> {
List<EquipmentGatewayRecord> gateways = equipmentIdToGatewaysMap.get(eqId);
if(gateways == null) {
gateways = new ArrayList<>();
equipmentIdToGatewaysMap.put(eqId, gateways);
}
List<EquipmentGatewayRecord> gwList = routingServiceInterface.getRegisteredGatewayRecordList(eqId);
if(gwList.isEmpty()) {
LOG.debug("Equipment {} is offline, command not delivered", eqId);
}
gateways.addAll(gwList);
});
//create a map of EquipmentGatewayRecord to a batch of command for that gateway
Map<EquipmentGatewayRecord, List<CEGWBaseCommand>> gatewayToCommandsMap = new HashMap<>();
equipmentIdToGatewaysMap.forEach( (eqId, gwList) -> gwList.forEach( gw -> {
List<CEGWBaseCommand> cmds = gatewayToCommandsMap.get(gw);
if(cmds == null) {
cmds = new ArrayList<>();
gatewayToCommandsMap.put(gw, cmds);
}
cmds.addAll(equipmentIdToCommandsMap.get(eqId));
}) );
// for each EquipmentGatewayRecords send the corresponding sub-batch of commands
gatewayToCommandsMap.forEach( (gw, cmds) -> {
ret.addAll(sendCommands(gw.getHostname(), gw.getPort(), cmds));
} );
// TODO resolve multiple responses per-command, if any
// (i.e. if one GW replied that equipment route is not found, and another GW replied with success, then the result should be success)
return ret;
}
public List<EquipmentCommandResponse> sendCommands(String gatewayHost, int gatewayPort, List<CEGWBaseCommand> commands) {
HttpEntity<String> request = new HttpEntity<>(commands.toString(), headers);
LOG.debug("Sending to gateway {}:{} commands {}", gatewayHost, gatewayPort, commands);
ResponseEntity<List<EquipmentCommandResponse>> responseEntity = restTemplate.exchange(
getProtocol() + "://" + gatewayHost + ":" + gatewayPort + "/commands",
HttpMethod.POST, request, EquipmentCommandResponse_LIST_CLASS_TOKEN);
List<EquipmentCommandResponse> ret = responseEntity.getBody();
LOG.debug("Response from gateway {}:{} {}", gatewayHost, gatewayPort, ret);
return ret;
}
public String getProtocol() {
if (protocol == null) {
protocol = environment.getProperty("tip.wlan.equipmentGatewayProtocol", "https").trim();
}
return protocol;
}
}

View File

@@ -0,0 +1,164 @@
package com.telecominfraproject.wlan.equipmentgateway.service;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import com.telecominfraproject.wlan.core.model.service.GatewayType;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBaseCommand;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBlinkRequest;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWCommandResultCode;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWConfigChangeNotification;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWStartDebugEngine;
import com.telecominfraproject.wlan.equipmentgateway.models.EquipmentCommandResponse;
import com.telecominfraproject.wlan.remote.tests.BaseRemoteTest;
import com.telecominfraproject.wlan.routing.RoutingServiceInterface;
import com.telecominfraproject.wlan.routing.models.EquipmentGatewayRecord;
import com.telecominfraproject.wlan.routing.models.EquipmentRoutingRecord;
//NOTE: these profiles will be ADDED to the list of active profiles
@ActiveProfiles(profiles = {
"integration_test",
"no_ssl","http_digest_auth","rest-template-single-user-per-service-digest-auth",
})
public class EquipmentGatewayServiceRemoteTest extends BaseRemoteTest {
@Autowired EquipmentGatewayServiceInterface testInterface;
@Autowired RoutingServiceInterface routingInterface;
@Before public void urlSetup(){
configureBaseUrl("tip.wlan.routingServiceBaseUrl");
addProperties("tip.wlan.equipmentGatewayProtocol", "http");
}
@Test
public void testEquipmentGateway_SingleCommand() {
long equipmentId = getNextEquipmentId();
int customerId = getNextCustomerId();
String inventoryId = "ap-"+ equipmentId;
//create gateway record
EquipmentGatewayRecord equipmentGwRecord = new EquipmentGatewayRecord(GatewayType.CEGW);
equipmentGwRecord.setHostname("localhost");
equipmentGwRecord.setIpAddr("127.0.0.1");
equipmentGwRecord.setPort(server.getWebServer().getPort());
equipmentGwRecord = routingInterface.registerGateway(equipmentGwRecord );
//create equipment routing record
EquipmentRoutingRecord eqRoutingRec = new EquipmentRoutingRecord();
eqRoutingRec.setCustomerId(customerId);
eqRoutingRec.setEquipmentId(equipmentId);
eqRoutingRec.setGatewayId(equipmentGwRecord.getId());
eqRoutingRec = routingInterface.create(eqRoutingRec);
//now we can send a command that uses the routing info we set up earlier
EquipmentCommandResponse ret = testInterface.sendCommand(new CEGWBlinkRequest(inventoryId , equipmentId ));
assertEquals(CEGWCommandResultCode.Success, ret.getResultCode());
}
@Test
public void testEquipmentGateway_BulkCommands() {
int customerId = getNextCustomerId();
//create gateway record
EquipmentGatewayRecord equipmentGwRecord = new EquipmentGatewayRecord(GatewayType.CEGW);
equipmentGwRecord.setHostname("localhost");
equipmentGwRecord.setIpAddr("127.0.0.1");
equipmentGwRecord.setPort(server.getWebServer().getPort());
equipmentGwRecord = routingInterface.registerGateway(equipmentGwRecord );
List<Long> equipmentIds = new ArrayList<>();
long eqId;
for(int i=0; i<10; i++) {
eqId = getNextEquipmentId();
equipmentIds.add(eqId);
//create equipment routing records
EquipmentRoutingRecord eqRoutingRec = new EquipmentRoutingRecord();
eqRoutingRec.setCustomerId(customerId);
eqRoutingRec.setEquipmentId(eqId);
eqRoutingRec.setGatewayId(equipmentGwRecord.getId());
eqRoutingRec = routingInterface.create(eqRoutingRec);
}
//now we can send a batch of commands that uses the routing info we set up earlier
//we'll prepare 3 commands per equipment Id
List<CEGWBaseCommand> cmdBatch = new ArrayList<>();
equipmentIds.forEach(equipmentId -> {
cmdBatch.add(new CEGWBlinkRequest("ap-" + equipmentId, equipmentId));
cmdBatch.add(new CEGWConfigChangeNotification("ap-" + equipmentId, equipmentId));
cmdBatch.add(new CEGWStartDebugEngine("ap-" + equipmentId, equipmentId, "testDebug", 4242 ));
});
List<EquipmentCommandResponse> ret = testInterface.sendCommands(cmdBatch);
assertEquals(cmdBatch.size(), ret.size());
ret.forEach(r -> assertEquals(CEGWCommandResultCode.Success, r.getResultCode()));
}
@Test
public void testEquipmentGateway_BulkCommands_multipleGateways() {
int customerId = getNextCustomerId();
// Create two gateway records.
// In real life only one GW record is valid per host/port, the other ones are considered stale.
// But in this test we are verifying that all the commands will be delivered to all the equipment across many gateways,
// so we are not concerned that several gateway records are created for the same host/port.
EquipmentGatewayRecord equipmentGwRecord1 = new EquipmentGatewayRecord(GatewayType.CEGW);
equipmentGwRecord1.setHostname("localhost");
equipmentGwRecord1.setIpAddr("127.0.0.1");
equipmentGwRecord1.setPort(server.getWebServer().getPort());
equipmentGwRecord1 = routingInterface.registerGateway(equipmentGwRecord1 );
EquipmentGatewayRecord equipmentGwRecord2 = new EquipmentGatewayRecord(GatewayType.CEGW);
equipmentGwRecord2.setHostname("localhost");
equipmentGwRecord2.setIpAddr("127.0.0.1");
equipmentGwRecord2.setPort(server.getWebServer().getPort());
equipmentGwRecord2 = routingInterface.registerGateway(equipmentGwRecord2 );
List<Long> equipmentIds = new ArrayList<>();
long eqId;
for(int i=0; i<10; i++) {
eqId = getNextEquipmentId();
equipmentIds.add(eqId);
//create equipment routing records even ones will use equipmentGwRecord1, odd ones will use equipmentGwRecord2
EquipmentRoutingRecord eqRoutingRec = new EquipmentRoutingRecord();
eqRoutingRec.setCustomerId(customerId);
eqRoutingRec.setEquipmentId(eqId);
eqRoutingRec.setGatewayId( (i%2==0) ? equipmentGwRecord1.getId() : equipmentGwRecord2.getId());
eqRoutingRec = routingInterface.create(eqRoutingRec);
}
//now we can send a batch of commands that uses the routing info we set up earlier
//we'll prepare 3 commands per equipment Id
List<CEGWBaseCommand> cmdBatch = new ArrayList<>();
equipmentIds.forEach(equipmentId -> {
cmdBatch.add(new CEGWBlinkRequest("ap-" + equipmentId, equipmentId));
cmdBatch.add(new CEGWConfigChangeNotification("ap-" + equipmentId, equipmentId));
cmdBatch.add(new CEGWStartDebugEngine("ap-" + equipmentId, equipmentId, "testDebug", 4242 ));
});
List<EquipmentCommandResponse> ret = testInterface.sendCommands(cmdBatch);
assertEquals(cmdBatch.size(), ret.size());
ret.forEach(r -> assertEquals(CEGWCommandResultCode.Success, r.getResultCode()));
}
}

View File

@@ -0,0 +1,45 @@
package com.telecominfraproject.wlan.opensync.external.integration.controller;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBaseCommand;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWCommandResultCode;
import com.telecominfraproject.wlan.equipmentgateway.models.EquipmentCommandResponse;
@RestController
public class OpensyncCloudGatewayController {
private static final Logger LOG = LoggerFactory.getLogger(OpensyncCloudGatewayController.class);
public static class ListOfEquipmentCommandResponses extends ArrayList<EquipmentCommandResponse> {
private static final long serialVersionUID = 3070319062835500930L;
}
{
LOG.info("***** Using mock OpensyncCloudGatewayController");
}
@RequestMapping(value = "/commands", method = RequestMethod.POST)
public ListOfEquipmentCommandResponses sendCommands(@RequestBody List<CEGWBaseCommand> commands) {
ListOfEquipmentCommandResponses ret = new ListOfEquipmentCommandResponses();
if(commands == null) {
return ret;
}
commands.forEach(command -> {
LOG.debug("sendCommands - processing {}", command);
ret.add(new EquipmentCommandResponse(CEGWCommandResultCode.Success, "", command, "mockGw", 4242) );
});
return ret;
}
}

View File

@@ -0,0 +1,32 @@
app.name=EquipmentGatewayService-Test
# Note: this property is additive, its value is always added to the list of active profiles
spring.profiles.include=no_ssl,http_digest_auth,rest-template-single-user-per-service-digest-auth,use_single_ds,test-email-sender
spring.main.show-banner=false
server.port=9084
#this server only supports REST requests, CSRF would get in the way
tip.wlan.csrf-enabled=false
#this user/password is used together with http_digest_auth spring profile
tip.wlan.serviceUser=user
tip.wlan.servicePassword=password
#used by *-remote client classes when they authenticate their requests
tip.wlan.httpClientConfig=classpath:httpClientConfig.json
#server.session-timeout= # session timeout in seconds
#server.tomcat.max-threads = 0 # number of threads in protocol handler
#server.context-path= # the context path, defaults to '/'
#server.servlet-path= # the servlet path, defaults to '/'
#server.tomcat.access-log-pattern= # log pattern of the access log
#server.tomcat.access-log-enabled=false # is access logging enabled
# pretty print JSON
spring.jackson.serialization.INDENT_OUTPUT=TRUE
# sort keys
#http.mappers.json-sort-keys=false
#spring.jmx.enabled=true # Expose MBeans from Spring

View File

@@ -0,0 +1,12 @@
{
"maxConnectionsTotal":100,
"maxConnectionsPerRoute":10,
"truststoreType":"",
"truststoreProvider":"",
"truststoreFile":"",
"truststorePass":"",
"credentialsList":[
{"host":"localhost","port":-1,"user":"user","password":"password"}
]
}

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<conversionRule conversionWord="filteredStack"
converterClass="com.telecominfraproject.wlan.server.exceptions.logback.ExceptionCompressingConverter" />
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%filteredStack%nopex</pattern>
<!-- See http://logback.qos.ch/manual/layouts.html for details -->
<!-- %ex{5} - add at the end to display only 5 levels of the exception stack trace -->
<!-- %nopex - add at the end to not display any of the exception stack traces -->
<!-- %ex{full} - add at the end to display all the levels of the exception stack trace -->
</encoder>
</appender>
<!--
details: http://logback.qos.ch/manual/configuration.html#auto_configuration
runtime configuration, if need to override the defaults:
-Dlogging.config=file:///home/ec2-user/opensync/logback.xml
for log configuration debugging - use
-Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener
log levels:
OFF ERROR WARN INFO DEBUG TRACE
-->
<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
<logger name="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" level="INFO"/>
<logger name="org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer" level="INFO"/>
<logger name="org.springframework.security.web.authentication.preauth" level="OFF"/>
<logger name="com.netflix.servo.tag.aws.AwsInjectableTag" level="OFF"/>
<logger name="com.telecominfraproject" level="WARN"/>
<logger name="com.telecominfraproject.wlan.equipmentgateway.service.EquipmentGatewayServiceRemote" level="DEBUG"/>
<root level="WARN">
<appender-ref ref="stdout"/>
</root>
</configuration>