<< Previous | Home

ZeroMQ - Thrift TwoWay-Communication

ZeroMQ-based thrift "peer" that is server (multiple services) and client in one. Using one router for punshing out.

See the github-repository for the source-code: https://github.com/dertom95/zeromq-thrift-p2p

  • What is it good for?

Ever used thrift but wanted a way the server could push calls to the client (and of course the client to the server). This version here is basically based on https://github.com/kdlan/thrift-zeromq but it implements this two-way communication as described using ZeroMQ

  1. Here a simple overview:

Local you have multiple ZeroMQ-Sockets that are connected to the Backend(0MQ-Router). You can implement multiple Thrift-Services and add those to the TZeroMQPeer. Each of which will reside in a Thread of its own. All of those are listening if any other peer want to call one of those services. Central point in this setup is the Router which will handle all calls for you and that must be reachable from each peer.

How does it work?

  1. Start an instance of Router (Router.java) somewhere. Let's assume we have it running locally on 127.0.0.1:9001(default-port)

  2. Create one peer with a service(as seen in TestZeroMQThriftServer.java):

		// create the peer that is Thrift Server and Client in one and connect to the Router which must be connectable for all other
		// clients
		final TZeroMQPeer peer = new TZeroMQPeer("server","tcp://127.0.0.1:9001");		
		
		// the implementation of the ServerService that will be handled by this server
		// so any other server (and actually me as well) can call this service via their Thrift-Client
		ServerService.Iface serverServiceImpl = new ServerService.Iface(){
			// some testdata
      List<User> users=new ArrayList<>();
			{
				users.add(new User("mixi", "mixi@tom.com"));
				users.add(new User("moxi", "moxi@tom.com"));
			}
			
			@Override
			public List<User> getOnlineUsers() throws TException {
				// with this call you can get the routing to the calling peer's ClientService
        String caller =  peer.getLocalService("ServerService").getCurrentCallerRoute("ClientService");
				clientTarget = caller;
				return users;
			}

			@Override
			public User addUser(String username, String email) throws TException {
				User newUser = new User();
				users.add(newUser);
				return newUser;
			}
			@Override
			public void printOnServer(String st) throws TException {
				// this is a oneway method, so the client won't wait for a reply
				System.out.println("Print on server:"+st);
			}
		};
		

		// Add the service we just created and make it available under the servicename 'ServerService' (case-sensitive)
		// You can create multiple service to be available. Each will reside in its own thread.
		peer.addService("ServerService", new ServerService.Processor<>(serverServiceImpl));

In order to call something on a connected peer:

    // Prepare a client-stub for ClientService-Calls on remote peers
		ClientService.Client client = new ClientService.Client(peer.getClientProtocol());

    // here happens the magic! You need to set the address to the client before sending via
		// peer. You need to know the path before. It is a dot-separated path like this "servername.servicename". Plz see that all servers need to have unique names, otherwise the Router won't do it's job properly and won't even complain. (The router has some glitches...). You can get this path also by using *peer.getLocalService("ServerService").getCurrentCallerRoute("ClientService")* inside of a service-call. With this call you get the routing-target for the calling server's service.		
		peer.setClientTarget(clientTarget);
		long start = System.currentTimeMillis();
		for (int i=0;i<10000;i++) {
			try {
				int sleepTime = 3000 + (int)(Math.random()*10000);
				Thread.sleep(sleepTime);
				System.out.println(servername+":send "+i);
				client.pushMessageToClient(servername+" is calling! "+i,95);
			} 
			catch (Exception te) {
				te.printStackTrace();
			}
		}		

On the other hand you need a Client-Peer that have a ClientService implemented and registered (as seen in TestZeroMQThriftClient). This is basically the same procedure as before, just ClientService instead of ServerService:

		final User currentUser = new User("Tommy", "tom@tomtom.com");

		// the implementation of the ClientService that will be handled by this
		// Client so that any other server (and actually me as well) can call this service
		// via their Thrift-Client
		ClientService.Iface clientServiceImpl = new ClientService.Iface() {

			@Override
			public User getCurrentClientUser() throws TException {
				return currentUser;
			}

			@Override
			public void pushMessageToClient(String msg, int msgCode) throws TException {
				System.out.println("Message from Server:" + msg + "|" + msgCode);
			}
		};

		TZeroMQPeer peer = new TZeroMQPeer("client", "tcp://127.0.0.1:9001");
		peer.addService("ClientService", new ClientService.Processor<>(clientServiceImpl));

		ServerService.Client server = new ServerService.Client(peer.getClientProtocol());
		// the name of the server should be known and the name of the service as well
    peer.setClientTarget("server.ServerService");
		long start = System.currentTimeMillis();
		try {
			List<User> users = server.getOnlineUsers();
			for (User u : users) {
				System.out.println("User:" + u);
			}
		} catch (Exception te) {
			te.printStackTrace();
		}
Tags : , ,

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

xText - use custom properties in CustomOutputConfigurationProvider

Ok, that is a very special topic and I guess not many will need this.
My problem was that I created a properties-page and wanted to use the folders selected there or to use IProject-related paths or such. I had to hack a little bit to get it to work, but I did it. In the end I could have context-based CustomOutputConfigurations.

Ok, I got it to work but it feels a bit hacky. Here is what I did.

  1. Write OutputConfigurationProvider that implements IContextualOutputProvider2 and place it somewhere in your MyDSL-Modules main-module
public class CustomOutputConfigurationProvider  implements IContextualOutputConfigurationProvider2 {

	override getOutputConfigurations(ResourceSet context) {
		if (context.resources.size()>0){
			// we are now context-aware. With the resource we can access the project
			val Resource res = context.resources.get(0);
			val path = res.URI.toPlatformString(true);
			val file = ResourcesPlugin.workspace.root.findMember(path) as IFile;
			val IProject project = file.project		
			// do what you want! e.g. read properties (as I intend to do)
			val OutputConfiguration defaultOutput = new OutputConfiguration(IFileSystemAccess.DEFAULT_OUTPUT);
			defaultOutput.setDescription("Default Output - Overwrite");
			defaultOutput.setOutputDirectory("./out-src/src-gen");
			defaultOutput.setOverrideExistingResources(true);
			defaultOutput.setCreateOutputDirectory(true);
			defaultOutput.setCleanUpDerivedResources(true);
			defaultOutput.setSetDerivedProperty(true);
			defaultOutput.useOutputPerSourceFolder = true;
			return newHashSet(defaultOutput);
		}
		return newHashSet();
	}
}
  1. Bind it in your MyDSLRuntimeModule:
	def Class<? extends IContextualOutputConfigurationProvider2> bindIContextualOutputConfigurationProvider2() {
		CustomOutputConfigurationProvider
	}

3)In the UI-Module create a CustomBuilderParticipant that derives from BuilderPartiticpant:

public class CustomBuilderParticipant extends BuilderParticipant {

	@Inject
	private IContextualOutputConfigurationProvider2 outputConfigurationProvider;
	
	@Override
	protected Map<String, OutputConfiguration> getOutputConfigurations(IBuildContext context) {
		Set<OutputConfiguration> configurations = outputConfigurationProvider.getOutputConfigurations(context
				.getResourceSet());
		return uniqueIndex(configurations, new Function<OutputConfiguration, String>() {
			@Override
			public String apply(OutputConfiguration from) {
				return from.getName();
			}
		});
	}
}
  1. Bind this in your UI-Modules MsDSLUIModule.xtend:
	override Class<? extends IXtextBuilderParticipant> bindIXtextBuilderParticipant() {
		return CustomBuilderParticipant;
	}

That's it. Seems to work. Also have a look at a corresponding forum-thread .

Tags : , ,

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Global Game Jam / Düren

It was GlobalGamJam and I decided to give it a shot. It was very attractive since there was a jam-site in Düren where I live. Very small one organized by headup games. (Big thank to them, Mark and Dieter).

Since I do need to get into Unity3d again, that was a perfect oppurtunity to do this. Nothing better than pressure (ok, I assume during the pressure-phase I wouldn't sign that phrase ;) ).

I make it short. I created a simple mixture. A 'zombie survival game' with two modes. One to set traps and the second to lead the player chasing zombies in these traps. There was a spring-trap, some fences to lead them in a direction and a bombtrap which you could fire. As always there was not much time for level-design. But hey, it was ok. Nothing fancy, and nothing that I couldn't have done with gamekit ;)

Here is the thing: About traps and zombies

EDIT: I now really played the game the first time after the jam and I have to say, I do like it! Beside there is some nasty bug that restarts the level from time to time when you jump. Beside this. Nicely done ;)



Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

ZeroMQ - Fun Part II

In this sample:

  • send data directly from target to service1
  • send data from service2 to target and back
package org.tt.zmq.tests;

import org.junit.Test;
import org.zeromq.ZContext;
import org.zeromq.ZMQ;
import org.zeromq.ZMsg;

/**
 * Here I will keep some tests to understand the behaviour of ZMQ-Socket-Types
 * 
 * @author dertom95
 *
 */
public class ZMQBTo2Dealers2 {

	private static void doProxy(ZMQ.Socket from, ZMQ.Socket to) {
		ZMsg msg = ZMsg.recvMsg(from);
		msg.send(to);
	}

	@Test
	public void testBoundRountTo2Dealers() {
		// create one context for each logical section to "simulate" different
		// computers

		// ------------ setup target -----------------------
		ZContext ctxTarget = new ZContext();

		ZMQ.Socket target = ctxTarget.createSocket(ZMQ.ROUTER);
		// give the socket an identity. this name will be used as address if
		// this socket connects to a router.
		// this is important if you want to route to a socket that didn't
		// contact you before
		target.setIdentity("target".getBytes());
		target.bind("tcp://127.0.0.1:9001");

		// ------------ setup proxy -------------------------
		ZContext ctxProxy = new ZContext();

		ZMQ.Socket dealer = ctxProxy.createSocket(ZMQ.DEALER);
		// give the dealer an identity. here it is actually important
		dealer.setIdentity("dealer".getBytes());
		dealer.connect("tcp://127.0.0.1:9001");
		ZMQ.Socket proxy = ctxProxy.createSocket(ZMQ.ROUTER);
		proxy.setIdentity("proxy".getBytes());
		proxy.bind("tcp://127.0.0.1:9000");

		// ----------- setup service ----------------------
		ZContext ctxServices = new ZContext();
		ZMQ.Socket service1 = ctxServices.createSocket(ZMQ.DEALER);
		// give the dealer an identity. here it is actually important
		service1.setIdentity("service1".getBytes());
		service1.connect("tcp://127.0.0.1:9000");

		ZMQ.Socket service2 = ctxServices.createSocket(ZMQ.DEALER);
		// give the dealer an identity. here it is actually important
		service2.setIdentity("service2".getBytes());
		service2.connect("tcp://127.0.0.1:9000");

		// ------------ actions -----------------------------

		// send data from server over the proxy to service1

		// let's create the message and tell which way it should go.
		// 1. go to socket that's identity is 'dealer' on the first
		// router-socket
		target.sendMore("dealer");
		// 2. go to socket that's identity is 'service1' on the 2nd
		// router-socket
		target.sendMore("service1");
		// 3. Give it the data and send this to target.
		// target-socket is our start-socket which is a router
		// this will pop the first line of our msg ('dealer') and checks if
		// there
		// is a socket called 'dealer' known to the router. If yes pass the rest
		// of
		// the message (without the 'dealer'-address) to this socket
		target.send("target greets you service1");

		// the target-router should have routed automatically to the
		// 'dealer'-socket
		// so we should be able receive the message
		// the job of the dealer is to get the message and to pass it as it is
		// to the
		// proxy which is a router socket.
		ZMsg dealerIncomingMsg = ZMsg.recvMsg(dealer);
		// check if the routing-address is "service1"
		String dealerIncomingAddress = dealerIncomingMsg.peekFirst().toString();
		assert (dealerIncomingAddress.equals("service1"));
		// send the message as it is to the proxy-router. this will take the
		// first-line as routing-address
		// checks also if this address is known and if yes it will pass the rest
		// of the message automatically to this socket
		dealerIncomingMsg.send(proxy);

		// Since service1-socket is connected to proxy-router and has the
		// identiy "service1" it should be able to receive
		// the message now.
		ZMsg service1Incoming = ZMsg.recvMsg(service1);
		String service1IncomingData = service1Incoming.popString();
		assert (service1IncomingData.equals("target greets you service1"));

		// now let's send a message from 'serivce2' to 'target'.
		// send the message to our own socket 'service2' which is connected to
		// proxy
		service2.send("hello target!");

		// therefore the data we send via service2 will end up in the
		// incoming-queue of proxy-socket
		ZMsg proxyIncomingMsg = ZMsg.recvMsg(proxy);
		// receiving(?) on a router-socket adds the address of the socket that
		// sent the message
		// to check the should beside the data there should now be an additional
		// address-line 'service2'
		String service2Address = proxyIncomingMsg.peekFirst().toString();
		assert (service2Address.equals("service2"));
		// send the message without doing something further to our dealer-proxy
		// which is connected to the target
		// therefore sending through 'dealer'-socket should make the message
		// available on target which is a router-socket.
		proxyIncomingMsg.send(dealer);

		// receive the message
		ZMsg targetIncomingMsg = ZMsg.recvMsg(target);
		// since target is also a router there should be a 2nd additional
		// address-line that points to the dealer, who sent
		// data from the dealer-socket to this target-socket
		String dealerAddress = targetIncomingMsg.peekFirst().toString();
		assert (dealerAddress.equals("dealer"));

		String data = targetIncomingMsg.getLast().toString();
		System.out.println("Got message from service2:" + data);

		// To send data BACK we can reuse the message
		// 1. get rid of the old data
		targetIncomingMsg.removeLast();
		// 2. add our new data
		targetIncomingMsg.addLast("Heyho, let's go!");
		// since in this message all routing information were created
		// automatically on the way from service1 to target
		// the message has everything its need to send data back to the caller
		targetIncomingMsg.send(target);

		// pass data from dealer to proxy (as we did when send directly from
		// target to service1 at the beginning)
		dealerIncomingMsg = ZMsg.recvMsg(dealer);
		dealerIncomingMsg.send(proxy);

		// now we should get the data again on our service2-socket
		ZMsg service2IncomingMsg = ZMsg.recvMsg(service2);
		data = service2IncomingMsg.popString();
		assert (data.equals("Heyho, let's go!"));
		System.out.println("Get some data back from target:" + data);

		ctxProxy.close();
		ctxServices.close();
		ctxTarget.close();
	}
}
Tags : , ,

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

ZeroMQ - Fun Part 1

ZeroMQ - Mindgames and Samples

Router bound, 2 Dealers connected to Router

Image

In this sample:

  • Send data from dealer1 to router
  • Create message to push data from router to dealer1 and dealer2
package org.tt.zmq.tests;

import java.nio.charset.Charset;

import org.junit.Test;
import org.zeromq.ZContext;
import org.zeromq.ZMQ;
import org.zeromq.ZMsg;

public class BRouterToCDealer {

	@Test
	public void testmain() {
		ZContext ctx = new ZContext();

		ZMQ.Socket router = ctx.createSocket(ZMQ.ROUTER);
		// give the socket an identity. this name will be used as address if
		// this socket connects to a router.
		// this is important if you want to route to a socket that didn't
		// contact you before
		router.setIdentity("router".getBytes());
		router.bind("tcp://127.0.0.1:9000");

		ZMQ.Socket dealer1 = ctx.createSocket(ZMQ.DEALER);
		// give the dealer an identity. here it is actually important
		dealer1.setIdentity("dealer1".getBytes());
		dealer1.connect("tcp://127.0.0.1:9000");

		ZMQ.Socket dealer2 = ctx.createSocket(ZMQ.DEALER);
		// give the dealer an identity. here it is actually important
		dealer2.setIdentity("dealer2".getBytes());
		dealer2.connect("tcp://127.0.0.1:9000");

		// send data to router
		dealer1.send("d1-data");
		// receive data as msg from router.
		// the router adds one frame with the address of the caller to be able
		// to send it back again
		ZMsg msg = ZMsg.recvMsg(router);
		// get that address that is added by the router
		String addressFromCaller = msg.popString();
		assert (addressFromCaller.equals("dealer1"));
		// get the actual data sent by dealer1
		String dataSentByCaller = msg.popString();
		assert (dataSentByCaller.equals("d1-data"));
		System.out.println("router got msg:" + msg);

		// send data from router to dealer1
		// stack togather:
		// first the address
		router.sendMore("dealer1");
		// followed by the data that should be sent to dealer1
		// the router gets the whole msg and expects the first frame to be a
		// routing-address
		// if this address is in a internal table it pops the address again and
		// sends the rest to this connection
		router.send("r1 - hi dealer1");

		// you can send as many msgs as you want (and as the router-queue can
		// handle)
		// now let's send a message to dealer2 using ZMsg
		ZMsg msgToD2 = new ZMsg();
		// here we have to stack upwards down.
		// first: the data
		msgToD2.push("r1 - hi dealer2");
		// second: the routing-address
		msgToD2.push("dealer2");
		msgToD2.send(router);

		// now let's receive the msgs the server sent
		msg = ZMsg.recvMsg(dealer1);
		String incomingMsgD1 = msg.popString();
		assert (incomingMsgD1.equals("r1 - hi dealer1"));
		System.out.println("dealer1:" + incomingMsgD1);
		// get the data directly from the socket
		String incomingDataD2 = dealer2.recvStr(Charset.defaultCharset());
		assert (incomingDataD2.equals("r1 - hi dealer2"));
		System.out.println("dealer2:" + incomingDataD2);
		// check if there are more parts left in the msgs we are now reading
		// line by line (in our case,no)
		boolean moreData = dealer2.hasReceiveMore();
		assert (!moreData);

		// close the context
		ctx.close();
	}
}
Tags : , ,

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Maven-Setup

Every time fun setting up a maven-project. Here is my minimal default-setup for:

  • an additional src-folder
  • setting up the compiler
  • creating a fat jar via: mvn assembly:once
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-assembly-plugin</artifactId>
				<configuration>
					<archive>
						<manifest>
							<mainClass>org.tt.zmq.security.Grasslands</mainClass>
						</manifest>
					</archive>
					<descriptorRefs>
						<descriptorRef>jar-with-dependencies</descriptorRef>
					</descriptorRefs>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>build-helper-maven-plugin</artifactId>
				<version>1.7</version>
				<executions>
					<execution>
						<id>add-source</id>
						<phase>generate-sources</phase>
						<goals>
							<goal>add-source</goal>
						</goals>
						<configuration>
							<sources>
								<source>src/main/gen-java</source>
							</sources>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

Tags : , ,

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

ZeroMQ using Java

Still have in my mind using ZeroMQ as Transport-Layer for my thrift-based communication between Server and Server and Server and Client. Therefore I took a deep look into JZMQ which is the JAVA-JNI Mapping for ZeroMQ. At the beginning I thought that Curve based encryptions wasn't built in yet, but it was only Certificate based authentification that wasn't implemented,yet. And even though I actually don't need to use it, I gave it a try to port it to Java.

This resulted in another pullrequest , let's see if that will be accepted, as this is something else than the former examples that I fixed for czmq. (EDIT: Just saw that travis is complaining about the jUnit-tests I wrote. One seems to keep blocking on OpenJDK6! Argh )

Using this I could port all security examples to java. Here as example the last certificate based authentication:

package org.tt.zmq.security;

import java.nio.charset.Charset;

import org.zeromq.ZAuth;
import org.zeromq.ZCert;
import org.zeromq.ZContext;
import org.zeromq.ZMQ;

//The Ironhouse Pattern
//
//Security doesn't get any stronger than this. An attacker is going to
//have to break into your systems to see data before/after encryption.
public class Ironhouse {

	private static final String CERTIFICATE_FOLDER=".curve";
	
	public static void main(String[] args) {
	    //  Create context
		ZContext ctx = new ZContext();
		
	    //  Start an authentication engine for this context. This engine
	    //  allows or denies incoming connections (talking to the libzmq
	    //  core over a protocol called ZAP).
		ZAuth auth = new ZAuth(ctx);
	    //  Get some indication of what the authenticator is deciding
	    auth.setVerbose(true);
	    //  Whitelist our address; any other address will be rejected
	    auth.allow("127.0.0.1");
	    //  Tell authenticator to use the certificate store in .curve
	    auth.configureCurve(CERTIFICATE_FOLDER);

	    //  We'll generate a new client certificate and save the public part
	    //  in the certificate store (in practice this would be done by hand
	    //  or some out-of-band process).
	    ZCert client_cert = new ZCert();
	    client_cert.setMeta("name", "Client test certificate");
	    client_cert.savePublic(CERTIFICATE_FOLDER+"/testcert.pub");
	    
	    ZCert server_cert = new ZCert();
	    
	    //  Create and bind server socket
	    ZMQ.Socket server = ctx.createSocket(ZMQ.PUSH);
	    server.setZAPDomain("global".getBytes());
	    server.setCurveServer(true);
	    server.setCurvePublicKey(server_cert.getPublicKey());
	    server.setCurveSecretKey(server_cert.getSecretKey());
	    server.bind("tcp://*:9000");
	    
	    //  Create and connect client socket
	    ZMQ.Socket client = ctx.createSocket(ZMQ.PULL);
	    client.setCurvePublicKey(client_cert.getPublicKey());
	    client.setCurveSecretKey(client_cert.getSecretKey());
	    client.setCurveServerKey(server_cert.getPublicKey());
	    client.connect("tcp://127.0.0.1:9000");
	    
	    //  Send a single message from server to client
	    server.send("Hello");
	    String message = client.recvStr(0,Charset.defaultCharset());
	    
	    if (message.equals("Hello")) {
	    	System.out.println("Ironhouse test OK");
	    }
	    ctx.close();
	}

}
Tags : , ,

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

ZeroMQ C-API, PULLREQUEST and now JAVA!?

Still working on the ZeroMQ-Front. And I am still convinced, now that I finished most of the guide. Actually I did plan to use JeroMQ but this pure Java ZeroMQ-Port seems to not have implemented security,yet.

Therefore I switched to the jni-Binding of libzmq which have everything implemented but the security (CURVE) that I wanted to use. :D The source-code says:

                if (self.mechanism.equals("PLAIN")) {
                    self.username = request.popString();
                    self.password = request.popString();
                } else if (self.mechanism.equals("CURVE")) {
                    // TODO: Handle CURVE authentication
                } else if (self.mechanism.equals("GSSAPI")) {
                    self.principal = request.popString();
                }

Nothing that shocks me too much. I'm not afraid to make my hands dirty. Therefore my plan was to first try security using C and then look if it is too complicated to get this mapped via jni.

Well, I found a wonderful article that describes everything about CURVE-based security with ZeroMQ,but for API v2 which is of course not compatible to API v3. ;) Took me some time to port those examples to compile with the current version of CZMQ, which is a 'High-level C binding for ZMQ'. Actually I found those files from the article as examples in the CZMQ-Git-repository and made a pullrequest for this. Let's see, what they have to say ;)
EDIT: Funny thing, while writing they accepted the pullrequest. Soooo proud ;)

Now I have two options:

  1. Write the proper mapping so I can get it work with JZMQ (the java-jni-binding)
  2. Write a function that creates everything I want and make it accessable via JNI.

But this have to wait till tomorrow. Now a little bit gamekit-fun :D

EDIT2: Ok, found out that JZMQ actually do have encryption built in and with this ZAP-Request you only have the final say if you are willing to allow or disallow a connection. Atm, I'm implementing CertStores for JZMQ, so only known clients are accepted as connecting clients. But this will be another post.
Links:

Tags : , , ,

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

ZeroMQ here we go

At the moment I'm working on a more distributed project. One central thing is that I want a local-server to be control from the main-server that is located somewhere else. (e.g. the internet) I'm using thrift-services and want on the one side to be able that the local-server can call the service-layer of the main-server and on the other side I want the main-server to be able to call the service-layer on the local-server.
'Real' clients connect via a separate port to the server's Client-Service-Layer.

I actually have a solution. I share the socket that is created by the local server when it connects to the main-server.

Meaning for the main-server:

  • incoming-data goes to the main-server-service-implementation
  • outgoing-data is mapped to a client of the local-server-thrift-client

The problem with this approach, you are forced to use oneway-calls in your thrift-service, which is a bit hacky if you want to give back information or want to throw exceptions. Otherwise you would have to label the traffic so everything is sent to the right requesting calls. (EDIT: Another approach could have been to open a second connection from client to server and to use on for the incoming and the other for the outgoing traffic )

current

Well, the oneway-call-approach works, nonetheless I have had the feeling that it is a bit too hacky. And since ZeroMQ is on my radar for some time already I throw the thrift-transport to the trash and create one based on ZeroMQ. Good chance to use it in a real project instead of just doing some samples or tutorials.

Btw, the ZeroMQ-guide is very good to read and quite good to follow and even funny ;) Here some quotes:

  • ...TCP has a long timeout (30 minutes or so), that means that it can be impossible to know whether a peer has died, been disconnected, or gone on a weekend to Prague with a case of vodka, a redhead, and a large expense account....
  • ...Let's see an example that pushes out weather updates consisting of a zip code, temperature, and relative humidity. We'll generate random values, just like the real weather stations do....
  • ...What it means is that it's safe to repeat an operation. Checking the clock is idempotent. Lending ones credit card to ones children is not...
    Links:
    Some read about thrift bidirectional-connection
    ZeroMQ-Guide

PS: Btw, this is the first blog-post I write with my markdown-plugin for pebble. (This should be a post of its own)

Tags : , , ,

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Build-Tool 'FUN'

Everytime I start with a new project I want to make it right from the start. And with this comes to write a proper build-file. No matter if this is cmake,ant,maven,gradle,premake... I end up thinking "Why the 'funk' is that so complicated and why is this not working what should obviously work...." I guess every new build-system started to make things easier but in the end it will end up in being an unintuitive mess.

Ok, I have to be honest. I'm not writing those build-files too often and have the "just do it"-approach, but hey. That have to be much simpler. Since I'm rotating between cmake, maven and ant I just forget from one project to another how things work... I really have to think about this and make things easier :)

Export this post as PDF document  Export this post to PDF document

Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

<< Previous | Home