Skip to content

Commit

Permalink
Nofify Node of listening port once server initialised.
Browse files Browse the repository at this point in the history
  • Loading branch information
pekim committed Apr 9, 2011
1 parent c844799 commit 7f17b19
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 51 deletions.
19 changes: 16 additions & 3 deletions node/node_modules/jdbc.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pom.xml
Expand Up @@ -33,7 +33,7 @@
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependency><!--
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
Expand All @@ -46,7 +46,7 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
--><dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.8</version>
Expand Down
46 changes: 31 additions & 15 deletions src/main/java/uk/co/pekim/nodejdbc/Main.java
Expand Up @@ -5,43 +5,59 @@
import org.apache.log4j.xml.DOMConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import uk.co.pekim.nodejdbc.configuration.Configuration;
import uk.co.pekim.nodejdbc.notifynode.NotifyInitialised;
import uk.co.pekim.nodejdbc.notifynode.NotifyNode;
import uk.co.pekim.nodejdbc.server.Server;

/**
* Node/JDBC bridge server.
*
* @author Mike D Pilsbury
*/
public class Main {
public final class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);

private final ApplicationContext context;
// private final ApplicationContext context;
private final Configuration configuration;

private Main(String configurationJson) {
private Main(final String configurationJson) {
this.configuration = Configuration.parseJson(configurationJson);
this.context = new ClassPathXmlApplicationContext(new String[] { "/uk/co/pekim/nodejdbc/nodejdbc.xml" });
// this.context = new ClassPathXmlApplicationContext(new String[] {
// "/uk/co/pekim/nodejdbc/nodejdbc.xml" });
}

private void run() {
LOGGER.info("Starting NodeJdbc server");
Object bean = context.getBean("testbean", TestBean.class);
LOGGER.info(bean.toString());

// Object bean = context.getBean("testbean", TestBean.class);
// LOGGER.info(bean.toString());

try {
new Server().run();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Server server = new Server();
server.start();

NotifyNode notifyNode = new NotifyNode(configuration.getNode().getPort());
notifyNode.send(new NotifyInitialised(server.getAddress().getPort()));

synchronized (this) {
wait();
}
} catch (IOException exception) {
throw new NodeJdbcException("Server problem", exception);
} catch (InterruptedException exception) {
throw new NodeJdbcException("Server problem", exception);
}
}

public static void main(String[] args) {
/**
* Run the server.
*
* @param args
* command arguments.
*/
public static void main(final String[] args) {
initialiseLogging();

try {
Expand Down
@@ -0,0 +1,32 @@
/**
*
*/
package uk.co.pekim.nodejdbc.notifynode;

/**
* Message to Node ifnormaing that we've initialised.
*
* @author Mike D Pilsbury
*/
public class NotifyInitialised {
private int port;

/**
* Create an initialisation message.
*
* @param port
* the port.
*/
public NotifyInitialised(final int port) {
this.port = port;
}

/**
* The port.
*
* @return the port
*/
public int getPort() {
return port;
}
}
68 changes: 68 additions & 0 deletions src/main/java/uk/co/pekim/nodejdbc/notifynode/NotifyNode.java
@@ -0,0 +1,68 @@
/**
*
*/
package uk.co.pekim.nodejdbc.notifynode;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import uk.co.pekim.nodejdbc.NodeJdbcException;
import uk.co.pekim.nodejdbc.netstring.Netstring;

/**
* Notify the parent Node process of various events.
*
* @author Mike D Pilsbury
*/
public class NotifyNode {
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();

private OutputStreamWriter output;

/**
* Create a Node notifier.
*
* @param port
* the port that a Node instance is listening on.
*/
public NotifyNode(final int port) {
try {
final Socket socket = new Socket(InetAddress.getLocalHost(), port);
output = new OutputStreamWriter(socket.getOutputStream());
} catch (UnknownHostException exception) {
throw new NodeJdbcException("Failed to connect to node", exception);
} catch (IOException exception) {
throw new NodeJdbcException("Failed to connect to node", exception);
}
}

/**
* Send a message to the Node instance. The message is send as a JSON
* representation of the message, wrapped in a netstring.
*
* @param message
* the message to send.
*/
public void send(final Object message) {
try {
final String jsonString = JSON_MAPPER.writeValueAsString(message);
final String netString = Netstring.build(jsonString);

output.write(netString);
output.flush();
} catch (JsonGenerationException exception) {
throw new NodeJdbcException("Failed to create JSON from " + message, exception);
} catch (JsonMappingException exception) {
throw new NodeJdbcException("Failed to create JSON from " + message, exception);
} catch (IOException exception) {
throw new NodeJdbcException("Failed to send JSON for " + message, exception);
}
}
}
54 changes: 29 additions & 25 deletions src/main/java/uk/co/pekim/nodejdbc/server/Server.java
Expand Up @@ -4,9 +4,11 @@
package uk.co.pekim.nodejdbc.server;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.glassfish.grizzly.filterchain.FilterChainBuilder;
import org.glassfish.grizzly.filterchain.TransportFilter;
import org.glassfish.grizzly.nio.transport.TCPNIOServerConnection;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder;
import org.slf4j.Logger;
Expand All @@ -21,40 +23,42 @@
public class Server {
private static final Logger LOGGER = LoggerFactory.getLogger(Server.class);

public static final String HOST = "localhost";
public static final int PORT = 7777;
private static final String HOST = "localhost";

public void run() throws IOException {
// Create a FilterChain using FilterChainBuilder
private InetSocketAddress address;

/**
* Run the server.
*
* @throws IOException
* exception
*/
public void start() throws IOException {
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();

// Add TransportFilter, which is responsible
// for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());

// StringFilter is responsible for Buffer <-> String conversion
filterChainBuilder.add(new NetStringFilter());
filterChainBuilder.add(new JsonFilter());

// Create TCP transport
final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();

transport.setProcessor(filterChainBuilder.build());
try {
// binding transport to start listen on certain host and port
transport.bind(HOST, PORT);

// start the transport
transport.start();

LOGGER.info("Press any key to stop the server...");
System.in.read();
} finally {
LOGGER.info("Stopping transport...");
// stop the transport
transport.stop();

LOGGER.info("Stopped transport...");
}

address = new InetSocketAddress(HOST, 0);
TCPNIOServerConnection serverConnection = transport.bind(0);
address = (InetSocketAddress) serverConnection.getLocalAddress();

LOGGER.info("Server bound to port " + address.getPort());

transport.start();
}

/**
* The address the server is bound to.
*
* @return the address
*/
public InetSocketAddress getAddress() {
return address;
}
}
12 changes: 6 additions & 6 deletions src/test/java/uk/co/pekim/nodejdbc/MainTest.java
Expand Up @@ -13,7 +13,7 @@ public class MainTest {
public void clearSecurityManager() {
System.setSecurityManager(null);
}

@Test(expected = ExitException.class)
public void testMissingJsonArg() {
System.setSecurityManager(new NoExitSecurityManager());
Expand All @@ -25,13 +25,13 @@ public void testMissingJsonArg() {
public void testBadJsonArg() {
System.setSecurityManager(new NoExitSecurityManager());

Main.main(new String[] {"bad"});
Main.main(new String[] { "bad" });
}

@Test
public void testGoodJsonArg() {
Main.main(new String[] {"{}"});
}
// @Test
// public void testGoodJsonArg() {
// Main.main(new String[] {"{}"});
// }

@SuppressWarnings("serial")
protected static class ExitException extends SecurityException {
Expand Down

0 comments on commit 7f17b19

Please sign in to comment.