Forum Discussion
@pperreault good stuff.
If I were to implement this in product I would probably write a regex with capture groups to match a valid user line. That way you can be more sure than the 9 column line is actually a user entry, and you can use the capture groups to easily dump out other items of interest.
This is a pretty common pattern in our core DataSources, most of the Nimble Storage stuff follows this pattern.
The regexes in those scripts might look scary but it's pretty easy to make in something like https://regexr.com
It's pretty solid looking for a first Groovy script. I would consider exiting the SSH session before you process the output, no need to keep that connection open after you have the data in a variable.
As far as error handling, you could wrap the initial Expect session setup in a try/catch. You can also use exitValue() on your Expect client object to ensure that your `show` command returned a successful return code before parsing the output.
Here's a pretty extreme example of a Groovy script with multiple return codes for specific issues:
import rocks.xmpp.addr.Jid import rocks.xmpp.core.XmppException import rocks.xmpp.core.sasl.AuthenticationException import rocks.xmpp.core.session.TcpConnectionConfiguration import rocks.xmpp.core.session.XmppClient import rocks.xmpp.core.session.XmppSessionConfiguration import rocks.xmpp.core.session.debug.ConsoleDebugger import rocks.xmpp.core.stanza.model.Message import javax.net.ssl.* // Server details, required def host = hostProps.get("system.hostname") def domain = hostProps.get("xmpp.domain") def port = hostProps.get("xmpp.port") ?: '5222' // Account details, required def sender = hostProps.get("xmpp.sender") def sender_pass = hostProps.get("xmpp.sender.pass") def receiver = hostProps.get("xmpp.receiver") def receiver_pass = hostProps.get("xmpp.receiver.pass") // Optional, disable starttls by setting to 'false' def use_ssl = hostProps.get("xmpp.ssl") ?: true // Optional, set to "true" to enable debug output in wrapper.log def debug = hostProps.get("xmpp.debug") ?: 'false' // Optional, change default authentication mechanism def auth_mechanism = hostProps.get("xmpp.authmech") ?: "PLAIN" // time to wait for expected message ( in seconds ) def timeout = hostProps.get("xmpp.message.timeout") ?: 5 // Check for required props if (!(sender && sender_pass && receiver && receiver_pass && domain)) { println 'missing required properties' println "xmpp.sender, xmpp.sender_pass, xmpp.receiver, xmpp.receiver_pass, and xmpp.domain are required" return 1; } // Used as a lock for synchronizing def received = new Object(); // Setup a bogus trust manager to accept any cert def nullTrustManager = [ checkClientTrusted: { chain, authType -> }, checkServerTrusted: { chain, authType -> }, getAcceptedIssuers: { null } ] // Setup a bogus hostname verifier def nullHostnameVerifier = [ verify: { hostname, session -> true } ] // Setup an SSL Context with the bogus TM and HV to accept any cert SSLContext sc = SSLContext.getInstance("SSL") sc.init(null, [nullTrustManager as X509TrustManager] as TrustManager[], null) public class NullHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } } HostnameVerifier verifier = new NullHostnameVerifier(); // Store send and receive timestamps so we can calculate RTT ( in millis ) def send_time = null def receive_time = null // Check debug option, setup session accordingly if (debug == 'true') { sessionConfiguration = XmppSessionConfiguration.builder() .debugger(ConsoleDebugger.class) .authenticationMechanisms(auth_mechanism) .build(); } else { sessionConfiguration = XmppSessionConfiguration.builder() .authenticationMechanisms(auth_mechanism) .build(); } // Setup connection config def tcpConfiguration = TcpConnectionConfiguration.builder() .hostname(host) // The hostname. .port(port.toInteger()) // The XMPP default port. .sslContext(sc) // Use an SSL context, which trusts every server. Only use it for testing! .hostnameVerifier(verifier) .secure(use_ssl) // We want to negotiate a TLS connection. .build(); // create the client instance def xmppClientSender = XmppClient.create(domain, sessionConfiguration, tcpConfiguration); def xmppClientReceiver = XmppClient.create(domain, sessionConfiguration, tcpConfiguration); // Add a message listener to the client instance xmppClientReceiver.addInboundMessageListener( { e -> // Get the message Message message = e.getMessage(); // Confirm that this message is from the expected sender if (message.from.toString() == "${sender}@${domain}/LMSENDER") { // Confirm that this message has the expected content if (message.body == "TESTMESSAGE") { // Record receive time receive_time = System.currentTimeMillis(); // Notify the parent thread that we can exit // synchronized must be used for notify() to work // received is our lock synchronized (received) { // notify the main thread to resume now that we have received the expected message. received.notify(); } } } }); // Try to connect the receiver client try { xmppClientReceiver.connect(); } catch (XmppException e) { println 'Receiver client failed to connect'; return 2; } // Try to connect the sender client try { xmppClientSender.connect(); } catch (XmppException e) { println 'Sender client failed to connect'; return 3; } // Try to login and send a message try { // We need to use synchronized here to call wait() on our lock object (received) // This will wait for a message event from the expected user with the expected content // The message handler will call notify() to resume this thread. // If we don't do this the client will close before we get the message. synchronized (received) { // Login with receiver account xmppClientReceiver.login(receiver, receiver_pass, 'LMRECEIVER') // Login with Sender account xmppClientSender.login(sender, sender_pass, 'LMSENDER') // Record time just before sending, so we can get RTT send_time = System.currentTimeMillis() // Send the message xmppClientSender.send(new Message(Jid.of("${receiver}@example.com"), Message.Type.CHAT, "TESTMESSAGE")) // Call wait() to block this thread until the message listener has called notify() // or until the timeout. received.wait(timeout * 1000) } if (send_time == null) { println "Message wasn't sent." return 4; } if (receive_time == null) { println "Message wasn't received." return 5; } // Print delivery time println receive_time - send_time } catch (AuthenticationException e) { println 'Authentication issue. Check your credentials.' println e; return 6; } catch (XmppException e) { println 'Something else went wrong with XMPP.' println e; return 7; } finally { // Close the connections xmppClientReceiver.close() xmppClientSender.close() } return 0;
Related Content
- 2 years ago
- 2 years ago
- 5 years ago