Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion usi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<version>5.6.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
Expand Down
169 changes: 169 additions & 0 deletions usi/src/main/java/daq/usi/BaseSwitchController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package daq.usi;

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public abstract class BaseSwitchController implements SwitchController {
/**
* Terminal Prompt ends with '#' when enabled, '>' when not enabled.
*/
public static final String CONSOLE_PROMPT_ENDING_ENABLED = "#";
Comment thread
grafnu marked this conversation as resolved.
public static final String CONSOLE_PROMPT_ENDING_LOGIN = ">";
public static final int TELNET_PORT = 23;

// Define Common Variables Required for All Switch Interrogators
protected SwitchTelnetClientSocket telnetClientSocket;
protected Thread telnetClientSocketThread;
protected String remoteIpAddress;
protected boolean debug;
protected String username;
protected String password;
protected boolean userAuthorised = false;
protected boolean userEnabled = false;
protected String hostname = null;
protected boolean commandPending = false;

public BaseSwitchController(String remoteIpAddress, String username,
String password) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check your style settings -- this should be hanging indent 4. Did it pass stickler/lint?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It passes stickler.mostly likely it means that rule is not configured.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually intellij won't even let me move this line to a less indented position. Is this a java syntax issue?

this(remoteIpAddress, username, password, false);
}

/**
* Abstract Switch controller. Override this class for switch specific implementation
*
* @param remoteIpAddress switch ip address
* @param username switch username
* @param password switch password
* @param debug for verbose logging
*/
public BaseSwitchController(
String remoteIpAddress, String username, String password, boolean debug) {
this.remoteIpAddress = remoteIpAddress;
this.username = username;
this.password = password;
this.debug = debug;
telnetClientSocket =
new SwitchTelnetClientSocket(remoteIpAddress, TELNET_PORT, this, debug);
}

/**
* Map a simple table containing a header and 1 row of data to a hashmap
* This method will also attempt to correct for mis-aligned tabular data as well as empty
* columns values.
*
* @param rawPacket Raw table response from a switch command
* @param colNames Array containing the names of the columns in the response
* @param mapNames Array containing names key names to map values to
* @return A HashMap containing the values mapped to the key names provided in the mapNames array
*/
protected static HashMap<String, String> mapSimpleTable(
String rawPacket, String[] colNames, String[] mapNames) {
HashMap<String, String> colMap = new HashMap<>();
String[] lines = rawPacket.split("\n");
if (lines.length > 0) {
String header = lines[0].trim();
String values = lines[1].trim();
int lastSectionEnd = 0;
for (int i = 0; i < colNames.length; ++i) {
int secStart = lastSectionEnd;
int secEnd;
if ((i + 1) >= colNames.length) {
// Resolving last column
secEnd = values.length();
} else {
// Tabular data is not always reported in perfectly alignment, we need to calculate the
// correct values based off of the sections in between white spaces
int firstWhiteSpace =
getFirstWhiteSpace(values.substring(lastSectionEnd)) + lastSectionEnd;
int lastWhiteSpace =
getIndexOfNonWhitespaceAfterWhitespace(values.substring(firstWhiteSpace))
+ firstWhiteSpace;
int nextHeaderStart = header.indexOf(colNames[i + 1]);
secEnd = Math.min(lastWhiteSpace, nextHeaderStart);
}
lastSectionEnd = secEnd;
String sectionRaw = values.substring(secStart, secEnd).trim();
colMap.put(mapNames[i], sectionRaw);
}
}
return colMap;
}

private static int getFirstWhiteSpace(String string) {
char[] characters = string.toCharArray();
for (int i = 0; i < string.length(); i++) {
if (Character.isWhitespace(characters[i])) {
return i;
}
}
return -1;
}

private static int getIndexOfNonWhitespaceAfterWhitespace(String string) {
char[] characters = string.toCharArray();
boolean lastWhitespace = false;
for (int i = 0; i < string.length(); i++) {
if (Character.isWhitespace(characters[i])) {
lastWhitespace = true;
} else if (lastWhitespace) {
return i;
}
}
return -1;
}

protected boolean containsPrompt(String consoleData) {
// Prompts usually hostname# or hostname(config)#
Pattern r = Pattern.compile(hostname + "\\s*(\\(.+\\))?" + CONSOLE_PROMPT_ENDING_ENABLED, 'g');
Matcher m = r.matcher(consoleData);
return m.find();
}

protected boolean promptReady(String consoleData) {
// Prompts usually hostname# or hostname(config)#
Pattern r = Pattern.compile(hostname + "\\s*(\\(.+\\))?" + CONSOLE_PROMPT_ENDING_ENABLED + "$");
Matcher m = r.matcher(consoleData);
return m.find();
}

/**
* Receive the raw data packet from the telnet connection and process accordingly.
*
* @param consoleData Most recent data read from the telnet socket buffer
*/
public void receiveData(String consoleData) {
if (debug) {
System.out.println(
java.time.LocalTime.now() + " receivedData:\t" + consoleData);
}
if (consoleData != null) {
try {
consoleData = consoleData.trim();
if (!userAuthorised) {
handleLoginMessage(consoleData);
} else if (!userEnabled) {
handleEnableMessage(consoleData);
} else {
parseData(consoleData);
}
} catch (Exception e) {
telnetClientSocket.disposeConnection();
e.printStackTrace();
}
}
}

protected abstract void parseData(String consoleData) throws Exception;

protected abstract void handleLoginMessage(String consoleData) throws Exception;

protected abstract void handleEnableMessage(String consoleData) throws Exception;

@Override
public void start() {
telnetClientSocketThread = new Thread(telnetClientSocket);
telnetClientSocketThread.start();
}
}
196 changes: 8 additions & 188 deletions usi/src/main/java/daq/usi/SwitchController.java
Original file line number Diff line number Diff line change
@@ -1,201 +1,21 @@
package daq.usi;

/*
* Licensed to Google under one or more contributor license agreements.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import grpc.Interface;
import grpc.Power;
import grpc.InterfaceResponse;
import grpc.PowerResponse;
import grpc.SwitchActionResponse;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public abstract class SwitchController implements Runnable {
/**
* Terminal Prompt ends with '#' when enabled, '>' when not enabled.
*/
public static final String CONSOLE_PROMPT_ENDING_ENABLED = "#";
public static final String CONSOLE_PROMPT_ENDING_LOGIN = ">";

// Define Common Variables Required for All Switch Interrogators
protected SwitchTelnetClientSocket telnetClientSocket;
protected Thread telnetClientSocketThread;
protected String remoteIpAddress;
protected int telnetPort;
protected boolean debug;
protected String username;
protected String password;
protected boolean userAuthorised = false;
protected boolean userEnabled = false;
protected String hostname = null;
protected boolean commandPending = false;

public SwitchController(String remoteIpAddress, int telnetPort, String username,
String password) {
this(remoteIpAddress, telnetPort, username, password, false);
}

/**
* Abstract Switch controller. Override this class for switch specific implementation
*
* @param remoteIpAddress switch ip address
* @param telnetPort switch telnet port
* @param username switch username
* @param password switch password
* @param debug for verbose logging
*/
public SwitchController(
String remoteIpAddress, int telnetPort, String username, String password, boolean debug) {
this.remoteIpAddress = remoteIpAddress;
this.telnetPort = telnetPort;
this.username = username;
this.password = password;
this.debug = debug;
telnetClientSocket =
new SwitchTelnetClientSocket(remoteIpAddress, telnetPort, this, debug);
}

protected boolean containsPrompt(String consoleData) {
// Prompts usually hostname# or hostname(config)#
Pattern r = Pattern.compile(hostname + "\\s*(\\(.+\\))?" + CONSOLE_PROMPT_ENDING_ENABLED, 'g');
Matcher m = r.matcher(consoleData);
return m.find();
}

protected boolean promptReady(String consoleData) {
// Prompts usually hostname# or hostname(config)#
Pattern r = Pattern.compile(hostname + "\\s*(\\(.+\\))?" + CONSOLE_PROMPT_ENDING_ENABLED + "$");
Matcher m = r.matcher(consoleData);
return m.find();
}

/**
* Receive the raw data packet from the telnet connection and process accordingly.
*
* @param consoleData Most recent data read from the telnet socket buffer
*/
public void receiveData(String consoleData) {
if (debug) {
System.out.println(
java.time.LocalTime.now() + " receivedData:\t" + consoleData);
}
if (consoleData != null) {
try {
consoleData = consoleData.trim();
if (!userAuthorised) {
handleLoginMessage(consoleData);
} else if (!userEnabled) {
handleEnableMessage(consoleData);
} else {
parseData(consoleData);
}
} catch (Exception e) {
telnetClientSocket.disposeConnection();
e.printStackTrace();
}
}
}

/**
* Map a simple table containing a header and 1 row of data to a hashmap
* This method will also attempt to correct for mis-aligned tabular data as well as empty
* columns values.
*
* @param rawPacket Raw table response from a switch command
* @param colNames Array containing the names of the columns in the response
* @param mapNames Array containing names key names to map values to
* @return A HashMap containing the values mapped to the key names provided in the mapNames array
*/
protected static HashMap<String, String> mapSimpleTable(
String rawPacket, String[] colNames, String[] mapNames) {
HashMap<String, String> colMap = new HashMap<>();
String[] lines = rawPacket.split("\n");
if (lines.length > 0) {
String header = lines[0].trim();
String values = lines[1].trim();
int lastSectionEnd = 0;
for (int i = 0; i < colNames.length; ++i) {
int secStart = lastSectionEnd;
int secEnd;
if ((i + 1) >= colNames.length) {
// Resolving last column
secEnd = values.length();
} else {
// Tabular data is not always reported in perfectly alignment, we need to calculate the
// correct values based off of the sections in between white spaces
int firstWhiteSpace =
getFirstWhiteSpace(values.substring(lastSectionEnd)) + lastSectionEnd;
int lastWhiteSpace =
getIndexOfNonWhitespaceAfterWhitespace(values.substring(firstWhiteSpace))
+ firstWhiteSpace;
int nextHeaderStart = header.indexOf(colNames[i + 1]);
secEnd = Math.min(lastWhiteSpace, nextHeaderStart);
}
lastSectionEnd = secEnd;
String sectionRaw = values.substring(secStart, secEnd).trim();
colMap.put(mapNames[i], sectionRaw);
}
}
return colMap;
}


private static int getFirstWhiteSpace(String string) {
char[] characters = string.toCharArray();
for (int i = 0; i < string.length(); i++) {
if (Character.isWhitespace(characters[i])) {
return i;
}
}
return -1;
}

private static int getIndexOfNonWhitespaceAfterWhitespace(String string) {
char[] characters = string.toCharArray();
boolean lastWhitespace = false;
for (int i = 0; i < string.length(); i++) {
if (Character.isWhitespace(characters[i])) {
lastWhitespace = true;
} else if (lastWhitespace) {
return i;
}
}
return -1;
}

protected abstract void parseData(String consoleData) throws Exception;

protected abstract void handleLoginMessage(String consoleData) throws Exception;

protected abstract void handleEnableMessage(String consoleData) throws Exception;
public interface SwitchController {

public abstract void getPower(int devicePort, ResponseHandler<Power> handler) throws Exception;
void getPower(int devicePort, ResponseHandler<PowerResponse> handler) throws Exception;

public abstract void getInterface(int devicePort, ResponseHandler<Interface> handler)
void getInterface(int devicePort, ResponseHandler<InterfaceResponse> handler)
throws Exception;

public abstract void connect(int devicePort, ResponseHandler<SwitchActionResponse> handler)
void connect(int devicePort, ResponseHandler<SwitchActionResponse> handler)
throws Exception;

public abstract void disconnect(int devicePort, ResponseHandler<SwitchActionResponse> handler)
void disconnect(int devicePort, ResponseHandler<SwitchActionResponse> handler)
throws Exception;

@Override
public void run() {
telnetClientSocketThread = new Thread(telnetClientSocket);
telnetClientSocketThread.start();
}
void start();
}
Loading