Skip to content

Commit

Permalink
IP range fix, ACS hotswap, configurable ID in header workaround, CSV …
Browse files Browse the repository at this point in the history
…parser for agent conf

* CpeActions: add check for missing dm paths for additional inform parameters

* CPEClientSession, CPEHttpServer, CPEWorker: make "strangeAcs" workaround to drop ID in Header configurable via agent config

* CPEHttpServer, CPEPeriodicInform, CPEWorker: take ACS URL, Username and Password from current dm state to properly handle ACS hotswap

* AgentConfig, SimulatorService: re-add support for IP ranges

* SimulatorService: introduce real CSV parser to handle special chars in agent.csv
  • Loading branch information
Luca Piccirillo committed Dec 6, 2024
1 parent 7261281 commit e2ff669
Show file tree
Hide file tree
Showing 9 changed files with 1,195 additions and 1,011 deletions.
6 changes: 5 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@


<dependencies>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.9</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
Expand Down Expand Up @@ -230,4 +235,3 @@
</plugins>
</build>
</project>

32 changes: 26 additions & 6 deletions src/main/java/com/paraam/cpeagent/AgentConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
* Structure to hold configuration information.
*/
public class AgentConfig {
private String ipAddress;
private String startIpAddress;
private String endIpAddress;
private String acsUrl;
private String simulatorLocation;
private int connectionRequestPort;
Expand All @@ -17,13 +18,22 @@ public class AgentConfig {
private String xmlFormat;
private String serialNumberFmt = "CPE%08d";
private int serialNumber = 0;
private boolean strangeAcs = false;

public String getIpAddress() {
return this.ipAddress;
public String getStartIpAddress() {
return this.startIpAddress;
}

public void setIpAddress(final String ipAddress) {
this.ipAddress = ipAddress;
public void setStartIpAddress(final String startIpAddress) {
this.startIpAddress = startIpAddress;
}

public String getEndIpAddress() {
return this.endIpAddress;
}

public void setEndIpAddress(final String endIpAddress) {
this.endIpAddress = endIpAddress;
}

public String getAcsUrl() {
Expand Down Expand Up @@ -121,11 +131,20 @@ public int getSerialNumber() {
public void setSerialNumber(int serialNumber) {
this.serialNumber = serialNumber;
}

public boolean getStrangeAcs() {
return this.strangeAcs;
}

public void setStrangeAcs(boolean strangeAcs) {
this.strangeAcs = strangeAcs;
}

@Override
public String toString() {
return "AgentConfig{" +
"ipAddress='" + ipAddress + '\'' +
"startIpAddress='" + startIpAddress + '\'' +
", endIpAddress='" + endIpAddress + '\'' +
", acsUrl='" + acsUrl + '\'' +
", simulatorLocation='" + simulatorLocation + '\'' +
", connectionRequestPort=" + connectionRequestPort +
Expand All @@ -138,6 +157,7 @@ public String toString() {
", xmlFormat='" + xmlFormat + '\'' +
", serialNumberFmt='" + serialNumberFmt + '\'' +
", serialNumber='" + serialNumber + '\'' +
", strangeAcs='" + strangeAcs + '\'' +
'}';
}
}
175 changes: 108 additions & 67 deletions src/main/java/com/paraam/cpeagent/SimulatorService.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.paraam.cpeagent;

import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

import com.bazaarvoice.dropwizard.assets.ConfiguredAssetsBundle;
Expand All @@ -15,6 +17,9 @@
import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.views.ViewBundle;

import com.opencsv.CSVParser;
import com.opencsv.CSVParserBuilder;

public class SimulatorService extends Service<SimulatorConfiguration> {
// names of environment variables provided for Dockerfile.
private static final String PI_INTERVAL = "PI_INTERVAL";
Expand All @@ -29,6 +34,7 @@ public class SimulatorService extends Service<SimulatorConfiguration> {
private static final String SERIAL_NUMBER_FORMAT = "SERIAL_NUMBER_FMT";
private static final String SERIAL_NUMBER = "SERIAL_NUMBER";
private static final String IP_ADDRESS = "IP_ADDRESS";
private static final String STRANGE_ACS = "STRANGE_ACS";

public static void main(final String[] args) throws Exception {
try {
Expand All @@ -46,100 +52,133 @@ public void initialize(final Bootstrap<SimulatorConfiguration> bootstrap) {
bootstrap.addBundle(GuiceBundle.newBuilder()
.addModule(new SimulatorModule())
.enableAutoConfig(getClass().getPackage().getName())
.build()
);
.build());
}

@Override
public void run(final SimulatorConfiguration configuration, final Environment environment) {
final AgentConfig config = this.readAgentConfig();
final String ipadr = config.getIpAddress();
final CPEWorker worker = new CPEWorker(ipadr, config.getConnectionRequestPort(), config.getAcsUrl(),
config.getConnectionRequestPath(), config.getPeriodicInformInterval(),
config.getSimulatorLocation(), config.getAuthUserName(), config.getAuthPassword(),
config.getAuthType(), config.getUserAgent(), config.getXmlFormat(),
config.getSerialNumberFmt(), config.getSerialNumber());
final CPEHttpServer httpserver = worker.getNewHttpServer();
Thread serverthread = new Thread(httpserver, "Http_Server");
serverthread.start();
final CPEPeriodicInform periodicInform = worker.getNewPeriodicInform();
Thread informthread = new Thread(periodicInform, "Periodic_Inform");
informthread.start();
final Thread cpthread = new Thread(worker, "WorkerThread_" + 0);
cpthread.start();
final ArrayList<AgentConfig> agentConfigs = this.readAgentConfig();
CPEUtil util = new CPEUtil();
int threadcnt = 0;

for (AgentConfig config : agentConfigs) {
ArrayList<String> iplist = new ArrayList<String>();
if (!util.isValidIPAddress(config.getStartIpAddress())) {
continue;
}
if (!util.isValidIPAddress(config.getEndIpAddress())) {
iplist.add(config.getStartIpAddress());
} else {
iplist = util.range2iplist(config.getStartIpAddress(), config.getEndIpAddress());
}

for (String ipaddr : iplist) {
final CPEWorker worker = new CPEWorker(ipaddr, config.getConnectionRequestPort() + threadcnt, config.getAcsUrl(),
config.getConnectionRequestPath(), config.getPeriodicInformInterval(),
config.getSimulatorLocation(), config.getAuthUserName(), config.getAuthPassword(),
config.getAuthType(), config.getUserAgent(), config.getXmlFormat(),
config.getSerialNumberFmt(), config.getSerialNumber() + threadcnt, config.getStrangeAcs());
final CPEHttpServer httpserver = worker.getNewHttpServer();
Thread serverthread = new Thread(httpserver, "Http_Server");
serverthread.start();
final CPEPeriodicInform periodicInform = worker.getNewPeriodicInform();
Thread informthread = new Thread(periodicInform, "Periodic_Inform");
informthread.start();
final Thread cpthread = new Thread(worker, "WorkerThread_" + threadcnt);
cpthread.start();
threadcnt++;
}
}
}

private AgentConfig readAgentConfig() {
private ArrayList<AgentConfig> readAgentConfig() {
final String confDir = "." + File.separator + "conf";
final String filepath = confDir + File.separator + "agent.csv";
//System.out.println("Current Filepath Checking >>>> " + filepath );
// System.out.println("Current Filepath Checking >>>> " + filepath );
final File userfile = new File(filepath);
AgentConfig config = userfile.exists() ? this.readAgentFile(filepath) : null;
ArrayList<AgentConfig> config = userfile.exists() ? this.readAgentFile(filepath) : null;
if (config == null) {
config = this.readAgentEnvironment();
config.add(this.readAgentEnvironment());
}
return config;
}

private AgentConfig readAgentFile(final String filepath) {
private ArrayList<AgentConfig> readAgentFile(final String filepath) {
CSVParser parser = new CSVParserBuilder()
.withSeparator(',')
.withIgnoreQuotations(false)
.build();
final CPEUtil util = new CPEUtil();
final ArrayList<String> csvlist = util.parseFile(filepath);
final ArrayList<String[]> tokenized = new ArrayList<String[]>();
for (final String line : csvlist) {
final String[] tokens = line.split(",");
if ((tokens.length > 0) && util.isValidIPAddress(tokens[0].trim()))
tokenized.add(tokens);
try {
String[] tokens = parser.parseLine(line);
if ((tokens.length > 0) && util.isValidIPAddress(tokens[0].trim())) {
tokenized.add(tokens);
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (tokenized.isEmpty()) {
return null;
}

final AgentConfig config = new AgentConfig();
final String[] csvline = tokenized.get(0);

//System.out.println("CSV Line >>>>>>>>> " + csvline);
if (csvline.length >= 7) {
config.setIpAddress(csvline[0].trim());
config.setAcsUrl(csvline[2].trim());
config.setConnectionRequestPath(csvline[3].trim());
final String crPortVal = csvline[4].trim();
config.setConnectionRequestPort(Integer.parseInt(crPortVal));
final String informInterval = csvline[5].trim();
config.setPeriodicInformInterval(Integer.parseInt(informInterval));
config.setSimulatorLocation(csvline[6].trim());
}
// defaults if not set in the file
config.setUserAgent("tr069-simulator");
config.setXmlFormat("");
config.setAuthType("");
config.setAuthUserName("user");
config.setAuthPassword("");

if (csvline.length >= 10) {
config.setAuthUserName(csvline[7].trim());
config.setAuthPassword(csvline[8].trim());
config.setAuthType(csvline[9].trim());
}
if (csvline.length >= 11) {
config.setUserAgent(csvline[10].trim());
}
if (csvline.length >= 12) {
config.setXmlFormat(csvline[11].trim());
}

if (csvline.length >= 13) {
config.setSerialNumberFmt(csvline[12].trim());
config.setSerialNumber(0);
}
if (csvline.length >= 14) {
config.setSerialNumber(Integer.parseInt(csvline[13].trim()));
final ArrayList<AgentConfig> agentConfigs = new ArrayList<AgentConfig>();

for (String[] csvline : tokenized) {
final AgentConfig config = new AgentConfig();

// System.out.println("CSV Line >>>>>>>>> " + csvline);
if (csvline.length >= 7) {
config.setStartIpAddress(csvline[0].trim());
config.setEndIpAddress(csvline[1].trim());
config.setAcsUrl(csvline[2].trim());
config.setConnectionRequestPath(csvline[3].trim());
final String crPortVal = csvline[4].trim();
config.setConnectionRequestPort(Integer.parseInt(crPortVal));
final String informInterval = csvline[5].trim();
config.setPeriodicInformInterval(Integer.parseInt(informInterval));
config.setSimulatorLocation(csvline[6].trim());
}
// defaults if not set in the file
config.setUserAgent("tr069-simulator");
config.setXmlFormat("");
config.setAuthType("");
config.setAuthUserName("user");
config.setAuthPassword("");

if (csvline.length >= 10) {
config.setAuthUserName(csvline[7].trim());
config.setAuthPassword(csvline[8].trim());
config.setAuthType(csvline[9].trim());
}
if (csvline.length >= 11) {
config.setUserAgent(csvline[10].trim());
}
if (csvline.length >= 12) {
config.setXmlFormat(csvline[11].trim());
}
if (csvline.length >= 13) {
config.setSerialNumberFmt(csvline[12].trim());
config.setSerialNumber(0);
}
if (csvline.length >= 14) {
config.setSerialNumber(Integer.parseInt(csvline[13].trim()));
}
if (csvline.length >= 15) {
config.setStrangeAcs(Boolean.parseBoolean(csvline[14].trim()));
}
agentConfigs.add(config);
}
return config;
return agentConfigs;
}

/**
* Intended to read external properties from environment variables. Mostly
* Useful in docker containers where this is an easier way to convey configuration.
* Useful in docker containers where this is an easier way to convey
* configuration.
*
* @return Agent configuration object.
*/
Expand All @@ -149,7 +188,7 @@ private AgentConfig readAgentEnvironment() {
config.setXmlFormat("");

final Map<String, String> environment = System.getenv();
config.setIpAddress(this.getOrDefault(SimulatorService.IP_ADDRESS, environment, "127.0.0.1"));
config.setStartIpAddress(this.getOrDefault(SimulatorService.IP_ADDRESS, environment, "127.0.0.1"));
final String piIntervalInSec = this.getOrDefault(SimulatorService.PI_INTERVAL, environment, "600");
config.setPeriodicInformInterval(Integer.parseInt(piIntervalInSec));
config.setAuthType(this.getOrDefault(SimulatorService.AUTH_TYPE, environment, ""));
Expand All @@ -165,6 +204,8 @@ private AgentConfig readAgentEnvironment() {
config.setSerialNumberFmt(this.getOrDefault(SimulatorService.SERIAL_NUMBER_FORMAT, environment, "%08d"));
final String serialNumberValue = this.getOrDefault(SimulatorService.SERIAL_NUMBER, environment, "0");
config.setSerialNumber(Integer.parseInt(serialNumberValue));
final String strangeAcsValue = this.getOrDefault(SimulatorService.STRANGE_ACS, environment, "false");
config.setStrangeAcs(Boolean.getBoolean(strangeAcsValue));

return config;
}
Expand Down
Loading

0 comments on commit e2ff669

Please sign in to comment.