Multiple SNMP Agents using SNMP4j and Java - java

I'm trying to create a snmp agent simulator application, that will create multiple virtual agents with unique ip address and port. I'm trying to use snmp4jagent. But i've some exceptions can you help me ?
I extend BaseAgent class to my own class then create Multiple Instance of that class. But I cannot start More than one agent at a time ie. if One agent's status is running i cannot start another agent without stopping the running agent (Code is too heavy So i don't specify any code here) code for starting an agent is
public void start() throws IOException
{
init();
addShutdownHook();
getServer().addContext(new OctetString("public"));
finishInit();
run();
sendColdStartNotification();
}
then i register Managed objects .
Code reference :
http://shivasoft.in/blog/java/snmp/creating-snmp-agent-server-in-java-using-snmp4j/
Thanks in advance
Pramod

It actually does work (as tested). Maybe you did not assign different IP addresses to your different instances. Add this to your class:
/**
* The ip address of this agent.
*/
private String ipAddress;
/**
* Initializes the transport mappings (ports) to be used by the agent.
*
* #throws IOException
*/
protected void initTransportMappings() throws IOException {
transportMappings = new TransportMapping[1];
transportMappings[0] = new DefaultUdpTransportMapping(new UdpAddress(ipAddress + "/161"));
}
You probably have to add the used ip addresses to your NIC. Example for Linux:
ip addr add 10.0.0.2/24 dev eth0
Please also provide exception messages and stacktraces if you still can't start asecond agent.

Related

How to get the automatically defined port for a Spark Java Application?

In the API documentation for Java Spark (not Apache spark), you can specify a port of 0 to have it automatically select a port. Great!
However, I cannot figure out how to get that port after the server is started. I can see it in the logs:
15:41:12.459 [Thread-2] INFO spark.webserver.JettySparkServer - >> Listening on 0.0.0.0:63134
But I need to be able to get to it programmatically, so that my integration tests are able to run reliably every time.
So how do I get that port?
I could find no way to get this information in the API, and so I filed an issue on their github.
I was able to get at it via an ugly pile of reflection:
/**
* Meant to be called from a different thread, once the spark app is running
* This is probably only going to be used during the integration testing process, not ever in prod!
*
* #return the port it's running on
*/
public static int awaitRunningPort() throws Exception {
awaitInitialization();
//I have to get the port via reflection, which is fugly, but the API doesn't exist :(
//Since we'll only use this in testing, it's not going to kill us
Object instance = getInstance();
Class theClass = instance.getClass();
Field serverField = theClass.getDeclaredField("server");
serverField.setAccessible(true);
Object oneLevelDeepServer = serverField.get(instance);
Class jettyServerClass = oneLevelDeepServer.getClass();
Field jettyServerField = jettyServerClass.getDeclaredField("server");
jettyServerField.setAccessible(true);
//Have to pull in the jetty server stuff to do this mess
Server jettyServer = (Server)jettyServerField.get(oneLevelDeepServer);
int acquiredPort = ((ServerConnector)jettyServer.getConnectors()[0]).getLocalPort();
log.debug("Acquired port: {}", acquiredPort);
return acquiredPort;
}
This works well for me in our integration tests, but I'm not using https, and it does reach about two levels deep into the API via reflection grabbing protected fields. I could not find any other way to do it. Would be quite happy to be proven wrong.
This will work on Spark 2.6.0:
public static int start (String keystoreFile, String keystorePw)
{
secure(keystoreFile, keystorePw, null, null);
port(0);
staticFiles.location("/public");
get(Path.CLOCK, ClockController.time);
get(Path.CALENDAR, CalendarController.date);
// This is the important line. It must be *after* creating the routes and *before* the call to port()
awaitInitialization();
return port();
}
Without the call to awaitInitialization() port() would return 0.

Unable to send SMS using java

I was just trying to send SMS using java as I require it in my Web App.But for testing purpose I am the code that is described in this site
And the code is as follows
package logic;
import com.harshadura.gsm.smsdura.GsmModem;
/**
* #author : Harsha Siriwardena <harshadura#gmail.com>
* #copyrights : www.Durapix.org <http://www.durapix.org>
* #license : GNU GPL v3 <http://www.gnu.org/licenses/>
*
* Example on how to simply send a SMS using the smsdura API Wrapper.
*/
public class TestSMS {
private static String port = "COM3"; //Modem Port.
private static int bitRate = 115200; //this is also optional. leave as it is.
private static String modemName = "ZTE"; //this is optional.
private static String modemPin = "0000"; //Pin code if any have assigned to the modem.
private static String SMSC = "+9477000003"; //Message Center Number ex. Mobitel
public static void main(String[] args) throws Exception {
GsmModem gsmModem = new GsmModem();
GsmModem.configModem(port, bitRate, modemName, modemPin, SMSC);
gsmModem.Sender("+94712244555", "Test Message"); // (tp, msg)
}
}
When I tried to run this,I am getting this error
-----------------------------
*** SMS-DURA - GSM MODEM SMS API WRAPPER ***
www.harshadura.com
-----------------------------
Example: Send message from a serial gsm modem.
SMSLib: A Java API library for sending and receiving SMS via a GSM modem or other supported gateways.
This software is distributed under the terms of the Apache v2.0 License.
Web Site: http://smslib.org
Version: 3.5.1
log4j:WARN No appenders could be found for logger (smslib).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" org.smslib.GatewayException: Comm library exception: java.lang.RuntimeException: javax.comm.NoSuchPortException
at org.smslib.modem.SerialModemDriver.connectPort(SerialModemDriver.java:102)
at org.smslib.modem.AModemDriver.connect(AModemDriver.java:114)
at org.smslib.modem.ModemGateway.startGateway(ModemGateway.java:189)
at org.smslib.Service$1Starter.run(Service.java:276)
Please anybody tell me how to fix this issue
basically you the program is unable to find the PORT,use
org.smslib.helper.CommPortIdentifier
to find the correct COM port from the list of ports.
I know this is not the sort of answer you expect on SO but given the alternative I think it's better than nothing.
a) Your library is reporting that your modem is not attached.
b) You don't know how to check if your modem is attached.
While not in any way related with the company I've used nexmo with great success in the past.
If it's a necessity of your app I would strongly suggest you approach the problem by the API route that will save you enormous amount of work.
There are several companies out there that provide this service and the usage is more or less straight-forward, you simply format a URL to pass parameters back to the company. Nexmo example:
// by calling a crafted url you are requesting the company to send the sms for you
urlString = "https://rest.nexmo.com/sms/json?api_key={api_key}&api_secret={api_secret}&from=MyCompany20&to=447525856424&text=helloworld";
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream()
Nexmo is NOT the only one out there providing this service. They are the only one i've had hands on experience with.
Copy the API(comm.jar),dll(win32com),properties file(javax.comm) in
1) If Net Beans tool you are using means
C:\Program Files\Java\jdk1.7.0\jre\lib\ext
and
C:\Program Files\Java\jdk1.7.0\jre\bin
2) If Eclipse tool you are using means
C:\Program Files\Java\jre7\lib\ext
and
C:\Program Files\Java\jre7\bin
as per the instructions given in Code projects.com where you downloaded this project.
Another way If you can configure your tool then do it, logic is the API's should be under your runtime JVM(jre).
and make sure that the port which is given by you should be free that is no other apps should run on it.
Yes I also got this exception to in Harshadura's SMS wrapper.Their can be two things you did not do
You did not declare any appenders in the code so at the beginning of
your code just type in this simple code to declare appenders.
package logic;
import com.harshadura.gsm.smsdura.GsmModem;
/**
* #author : Harsha Siriwardena <harshadura#gmail.com>
* #copyrights : www.Durapix.org <http://www.durapix.org>
* #license : GNU GPL v3 <http://www.gnu.org/licenses/>
*
* Example on how to simply send a SMS using the smsdura API Wrapper.
*/
public class TestSMS {
private static String port = "COM3"; //Modem Port.
private static int bitRate = 115200; //this is also optional. leave as it is.
private static String modemName = "ZTE"; //this is optional.
private static String modemPin = "0000"; //Pin code if any have assigned to the modem.
private static String SMSC = "+9477000003"; //Message Center Number ex. Mobitel
public static void main(String[] args) throws Exception {
BasicConfigurator.configure();//Declares appenders
GsmModem gsmModem = new GsmModem();
GsmModem.configModem(port, bitRate, modemName, modemPin, SMSC);
gsmModem.Sender("+94712244555", "Test Message"); // (tp, msg)
} }
Identifying the port of your GSM modem. This you can solve by going to your My Computer Icon click manage > click device manager> click modems and Identify the port of your modem.
The port you identifed then write it on your code.String port="MyPort";

How to discover the IP address of a Tomcat server on a network?

I have a Android application which consumes a webservice on a local network. There's a config screen where the user inform the server IP address, which is running Apache Tomcat.
I'm looking for a way to auto-detect the server based on the current connected wi-fi network.
i.e: The smartphone's IP is 10.1.1.90 and the server IP is 10.1.1.254.
Is there a way to achieve this? I'm thinking on using ping, but I don't know if is a good ideia.
The way I understand it, you need to discover IP of your tomcat server and connect it using your client.
I am assuming , both the server and client is in your control.
One simple way can be to use jGroups Cluster.
You can make your tomcat discoverable
Client can discover it using the name of the cluster you have provided .Refer the JChannel API that Jgroups uses
I simulated it making following server class
public class TomcatServer {
JChannel channel;
private void start() throws Exception {
channel = new JChannel(); // use the default config, udp.xml
channel.connect("TomcatCluster");
}
public static void main(String[] args) throws Exception {
new TomcatServer().start();
}
}
The simulated client class
public class MobileApp extends ReceiverAdapter {
JChannel channel;
private void start() throws Exception {
channel = new JChannel(); // use the default config, udp.xml
channel.setReceiver(this);
channel.connect("TomcatCluster");
channel.close();
}
public static void main(String args[]) throws Exception {
new MobileApp().start();
}
The client will provide you following information
GMS: address=MACHINENAME-47879, cluster=TomcatCluster, physical address=xxxxx:0:xxx:xxxx:xxxx:xxxx:xxx:xxxx:xxxx
** view: [MACHINENAME-31239|1] [MACHINENAME-31239, MACHINENAME-47879]
Where MACHINENAME-47879 is the client machine and port & MACHINENAME-31239 is the tomcat server name and port
Do you want to detect "a tomcat server" or "your tomcat server" ?
I mean, do you have any way to custom your server ? If it's the case, then you could create a very simple test page on your server (say a "Hello" JSP page), which your Android application could look for.
If your Android gets a "Hello" result with a GET request on http://<tomcat_ip>/hello.jsp, then you may assume that the tomcat is online.
If you can't add this test page, then you can test any page which the server is supposed to serve. (even a 404 page which sometimes is not configured well, and shows the tomcat version...)
Tomcat response headers can contain the xpoweredBy field that would advertise Tomcat if enabled. However it is most often disabled due security considerations, and even disabled by default. You however could re-enable it if you need to auto-detect exactly your Tomcat servers. From the other side, indeed, if you can place a web page on your server, you can simply place a marking page with the agreed signature.
If the server IP is unknown, I would propose the following ways to detect the server on the network:
The most straightforward way is to do the breadcast ping (ping -b broadcast_address where breadcast address can be computed here, for instance). All network devices that are configured so would reply, then verify as explained above which one is the server. However pinging broadcast address requires a rooted phone. Also the router may not support.
Your DHCP service (most likely your router) can often be configured to issue always the same IP address for the same MAC address of your server network card.
If the server is a desktop computer or laptop, it could show its address as QR code on display. It is possible for a smartphone to scan the code from the screen, and this is way easier than to enter IP address through the touchscreen. QR code can also include auto-generated password for extra security.
If there is wireless router with the possible login where both server and client are connected, the internal pages of that router often contain the relevant IP addresses. You would need to implement logging into the router and doing some screen scrapping.
I made an Android app which used a local server in the WLAN. I made the terminal (the phone) broadcast it's own IP address, which the server then picked up.
I used MultiCast class on the phone, which added the ip-address of itself to the payload. The server always has a thread in multicast read class that obains the payload of the packet (which is the terminals ip-address). Set the terminal in datagram read state and send the servers ip-address to terminal.
Maybe are better ways, but a great way to get the ip-addresses of unknown terminals in the network.
The way i had resolved this problem is with the use of enumerations.
public String getLocalIpAddress()
{
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (Exception ex) {
}
return null;
}
}

Communication between two Machines using java

I have Gui Application written which running on windows,and i want to connect to remote unix machine and perform actions there such like API's ,go over the log file in the machines and send back to the application the last log file or others API that i want to perform on the remote machine.
In the remote machine i don;t have application server i just have Java which installed there.
I want to use Java in order to perform remote API over the remote machine;
what is the advice ,can i use web services ,can any one please advise.
Thanks in advance.
If Java can perform the actions you're talking about, I would use Sockets to communicate with the UNIX-Machine (over TCP/IP).
Your Windows-PC would be the client sending commands to the Unix-PC.
Web services would be a bit heavy handed option, esp if you opt for the SOAP ones. If you don't have a problem with the client and server always being Java, RMI seems to be the simplest solution to this problem since it's communication between two different JVM's using the normal method calling mechanism (with some additional interfaces and rules to be followed to please the RMI specification).
The Spring Framework ships with a number of remoting options that are all very easy to setup. You can use their classes for simpler configuration of something standard like RMI or JMS, or use a lightweight web services protocol such as Spring's HTTP invoker or Hessian.
For analyzing log files of remote machines you can always use Apache Commons sftp programmatically to FTP a copy of the remote log file to your PC.
If you configure the log files to be rotatable or to rotate each time they reach a specific size, you can avoid reloading the same information over and over.
You can use Ganymed SSH-2 for Java to ssh to the remote host from Client Java App and run the commands. No need to run any additional components on remote server. You can do password based authentication or key based authentication to login to remote host. We had successfully used it to administer (start/stop/grep log files, etc.) applications running on remote UNIX hosts. You can capture output of the remote command using the StreamGobbler class provided in the package. You can pass multiple commands separated by semi-colon in one remote call.
Basic Example included in the package:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class Basic
{
public static void main(String[] args)
{
String hostname = "127.0.0.1";
String username = "joe";
String password = "joespass";
try
{
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* Now connect */
conn.connect();
/* Authenticate.
* If you get an IOException saying something like
* "Authentication method password not supported by the server at this stage."
* then please check the FAQ.
*/
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* Create a session */
Session sess = conn.openSession();
sess.execCommand("uname -a && date && uptime && who");
System.out.println("Here is some information about the remote host:");
/*
* This basic example does not handle stderr, which is sometimes dangerous
* (please read the FAQ).
*/
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true)
{
String line = br.readLine();
if (line == null)
break;
System.out.println(line);
}
/* Show exit status, if available (otherwise "null") */
System.out.println("ExitCode: " + sess.getExitStatus());
/* Close this session */
sess.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
System.exit(2);
}
}
}

How can I emulate a COM port, write data to it and read data from it?

I'm trying to test my code that reads from a USB port (COM25 when the device is connected) that is created when a device is connected to my computer and to a boat. I cannot power the USB device when not on the boat so testing is difficult. Can someone let me know how to simulate a COM port and write data to it so my test program is able to connect to that simulated COM port and read that data?
I'm reading this from a Java program but the simulation doesn't need to be in Java or any specific language. Just a program that will simulate the COM port and allow me to connect to it. I downloaded a COM port emulator from AGG Software and it appears that it's writing to what I deem COM25 but I'm not able to connect to it from my Java test.
The general answer for this kind of problem is to wrap the code that talks to the COM port in a class that implements an interface. If you do this as a Facade (pattern) then you can also make the COM methods you call sensible from your end.
The interface can then be mocked or faked for the test. (There is a great article on test objects, but I haven't been able to find it yet.) One advantage here is that you can create a fake version that throws exceptions or otherwise does things that are possible for the port to do but hard to get it to do in practice.
Where I work, we solved a similar issue by having our emulator not spoof a COM port at all. Here's how you can do it:
Define an interface for talking with your COM port, something like IUsbCommService
Implement your real COM-communcation service, using the standard Java Comm API
For your emulator, simply kick of a thread that spits out the same sort of data you can expect from your USB device at regular intervals.
Use your IOC framework of choice (e.g., Spring) to wire up either the emulator or the real service.
As long as you hide your implementation logic appropriately, and as long as you code to your interface, your service-consumer code won't care whether it's talking to the real USB device or to the emulator.
For example:
import yourpackage.InaccessibleDeviceException;
import yourpackage.NoDataAvailableException;
public interface IUsbProviderService {
public void initDevice() throws InaccessibleDeviceException;
public UsbData getUsbData()
throws InaccessibleDeviceException, NoDataAvailableException;
}
// The real service
import javax.comm.SerialPort; //....and the rest of the java comm API
public class UsbService implements IUsbProviderService {
.
.
.
}
// The emulator
public class UsbServiceEmulator implements IUsbProviderService {
private Thread listenerThread;
private static final Long WAITTIMEMS = 10L;
private String usbData;
public UsbServiceEmulator(long maxWaitTime) throws InaccessibleDeviceException{
initialize();
boolean success = false;
long slept = 0;
while (!success && slept < maxWaitTime) {
Thread.sleep(WAITTIMEMS);
slept += WAITTIMEMS;
}
}
private void initialize() throws InaccessibleDeviceException{
listenerThread = new Thread();
listenerThread.start();
}
private class UsbRunner implements Runnable {
private String[] lines = {"Data line 1", "Data line 2", "Data line 3"};
public void run() {
int line = 0;
while(true) {
serialEvent(lines[line]);
if(line == 3) {
line = 0;
} else {
line++;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
//handle the error
}
}
private void serialEvent(String line) {
if(/*you have detected you have enough data */) {
synchronized(this) {
usbData = parser.getUsbData();
}
}
}
}
Hope this helps!
Thanks to all the answers so far! Here's what I ended up doing as a result of recommendations from someone at work.
Downloaded the COM Port Data Emulator (CPDE) from AGG Software
Downloaded the Virtual Serial Port Driver (VSPD) from Eltima Software
(I just randomly picked a free data emulator and virtual serial port package. There are plenty of alternatives out there)
Using VSPD, created virtual serial ports 24 and 25 and connected them via a virtual null modem cable. This effectively creates a write port at 24 and a read port at 25.
Ran the CPDE, connected to 24 and started writing my test data.
Ran my test program, connected to 25 and was able to read the test data from it
There are plenty of relevant answers in this section. But as for me, I personally use Virtual Serial Port Driver, which works perfect for me. But I must admit that there are plenty alternatives when it comes to creating virtual ports: freevirtualserialports.com; comOcom to name a few. But I haven't got a chance to use them, so my recommendation for solving this problem is Virtual Serial Port Driver.
I recommend fabulatech's virtual modem.
Get it at http://www.virtual-modem.com
You might also want to get a COM port monitor for your tests - You can find it at
http://www.serial-port-monitor.com
Good luck with the boat! :)
I use com0com and it works great for what I need.
In addition all others, I would like to added this nice, free emulator https://sites.google.com/site/terminalbpp/ I do use. I do also use AGG Com port data emulator.

Categories

Resources