Author Archives: Helena Edelson

JInterface Can not connect to Peer Node

I ran into a nasty issue with jinterface when making a rapid succession of calls at the start of the application. I need to move this to a caching solution of the connections today but here is a quick solution for anyone else hitting their head against the wall with this. Jinterface swallows exception causes and it is very hard to hunt down the true underlying error. You will see the same error message for n-number of things that can go wrong farther down the stack.

First I’ve not added a boolean setter for if you want to use unique each time or not, so that’s something you can add. Also there’s a connection monitor for shared connections. I’ve left out all error handling for brevity. And finally, also for brevity, just used one constructor using the cookie to keep this shorter.

public class ConnectionFactory {

    private String cookie;
    private String selfNodeName;
    private String peerNodeName;
    private OtpSelf otpSelf;
    private OtpPeer otpPeer;
    private OtpConnection otpConnection;
    private final Object connectionMonitor = new Object();

    public ConnectionFactory(String selfNodeName, String cookie, String peerNodeName) {
		this.selfNodeName = selfNodeName;
		this.cookie = cookie;
		this.peerNodeName = peerNodeName;
                initialize();
    }

    public void initialize() {
		// assertions...
		String selfName = this.selfNodeName + "-" + UUID.randomUUID().toString();

		try {
			this.otpSelf = new OtpSelf(selfName.trim(), this.cookie);
		} catch (IOException e) {
			//
		}
		this.otpPeer = new OtpPeer(this.peerNodeName.trim());
	}

	public OtpConnection createConnection() {
		synchronized (this.connectionMonitor) {
			if (this.otpConnection == null) {
				try {
					doCreateConnection();
				} catch (IOException e) {
					//
				} catch (OtpAuthException e) {
                                 //
                         }
                  }
		return this.otpConnection;
		}
	}

	public void doCreateConnection() throws IOException, OtpAuthException {
		synchronized (this.connectionMonitor) {
			if (this.otpConnection != null) {
                             otpConnection.close();
			}

                       this.otpConnection = otpSelf.connect(otpPeer);
		}
	}

	public void destroy() {
		resetConnection();
	}

	public void resetConnection() {
		synchronized (this.connectionMonitor) {
			if (this.otpConnection != null) {
				otpConnection.close();
			}
			this.otpConnection = null;
		}
	}
}

Share/Save

Configuring @Configuration ApplicationContext for Spring Test Framework @ContextConfiguration

Here is a @Configuration class, RabbitTestConfiguration, truncated for the sake of a simple example. Bootstrapping this for testing using Spring’s Test Framework is simple. First make sure you have @ImportResource mapping via classpath to your xml which here has 2 simple declarations:


<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<component-scan base-package=”org.hyperic.hq.plugin.rabbitmq”/>

<property-placeholder location=”/etc/test.properties”/>

</beans:beans>

Next, make sure you remove the @Configuration annotation declared at the class level. We will be bootstrapping this a different way.

@ImportResource("classpath:/org/hyperic/hq/plugin/rabbitmq/*-context.xml")
public class RabbitTestConfiguration {

    private @Value("${hostname}") String hostname;

    private @Value("${username}") String username;

    private @Value("${password}") String password;

    @Bean
    public SingleConnectionFactory singleConnectionFactory() {
        SingleConnectionFactory connectionFactory = new SingleConnectionFactory(hostname);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }
// ... shortened for brevity
}

Now let’s build an abstract Spring base test

/**
 * AbstractSpringTest
 * @author Helena Edelson
 */
@ContextConfiguration(loader = TestContextLoader.class)
@RunWith(SpringJUnit4ClassRunner.class)
public abstract class AbstractSpringTest {
    /** Inheritable logger */
    protected final Log logger = LogFactory.getLog(this.getClass().getName());

    /** Now we can autowire our beans that all child tests will need. Note that they are protected. */
    @Autowired
    protected org.springframework.amqp.rabbit.connection.SingleConnectionFactory singleConnectionFactory;

   @Before
    public void before() {
        assertNotNull("singleConnectionFactory should not be null", singleConnectionFactory);
        //... more assertion checks for other beans, removed for brevity.
    }

And finally, build a test context loader, override customizeContext() and bootstrap your annotational config class. Since the config class bootstraps the minimal context xml config, now we’re all set.

/**
 * TestContextLoader
 * @author Helena Edelson
 */
public class TestContextLoader extends GenericXmlContextLoader {

    @Override
    protected void customizeContext(GenericApplicationContext context) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.register(RabbitTestConfiguration.class);
        ctx.refresh();
        /** This is really the key */
        context.setParent(ctx);
        assertTrue(ctx.isRunning());
    }
}

Now all of my Spring test classes can simply extend the base class and freely call the inherited shared beans or declare any @Autowired dependency

public class RabbitGatewayTest extends AbstractSpringTest {
     @Autowired protected Queue marketDataQueue;

    @Test
    public void getConnections() throws Exception {
        com.rabbitmq.client.Connection conn = singleConnectionFactory.createConnection();
        // ... etc
    }
}

Share/Save

Open Artificial Intelligence for the Cloud – Initial Diagram

This is a working (initial) idea of where an AI appliance might fit into a virtualized, elastic environment. I will update this concept soon as I created it early this summer and have many changes to now make to it. The parent post: Open Source Artificial Intelligence for the Cloud

© Copyright – not for re-use.

Share/Save

Open Source Artificial Intelligence for the Cloud

The idea of introducing intelligent computing so that software can make decisions autonomously and in real time is not new but it is relatively new to the cloud. Microsoft seems to be the strongest force in this realm currently but this is not open source. The idea of clouds that manage themselves steps way beyond Cloud Ops as we know it, and is the only logical, and necessary, next step.

I’ve been researching various open source AI platforms and learning algorithms to start building a prototype for cloud-based learning and action for massive distributed Cloud Ops systems and applications. Once could off er an AI cloud appliance eventually but I will start with a prototype and build on that using RabbitMQ (an AMQP messaging implementation), CEP, Spring, Java as a base. I’ve been looking into OpenStack, the open source cloud computing software being developed by NASA, RackSpace, and many others. Here is the future GitHub repo: http://github.com/helena/OCAI.

Generally to do these sort of projects you need a large amount of funding and engineers with PhD’s, none of which I have. So my only alternative is to see how we might take this concept and create a light weight open source solution.

Imagine having some of these (this being not a comprehensive list) available to your systems:

AI Technology

  • Planning and Scheduling
  • Heuristic Search
  • Temporal Reasoning
  • Learning Models
  • Intelligent Virtual Agents
  • Autonomic and Adaptive Clustering of Distributed Agents
  • Clustering Autonomous Entities
  • Constraint Predictability and Resolution
  • Automated Intelligent Provisioning
  • Real-time learning
  • Real-world action
  • Uncertainty and Probabilistic Reasoning
  • Decision Making
  • Knowledge Representation

I will go into these topics further in future posts.

About me: I am currently an engineer at SpringSource/VMware on the vFabric Cloud Application Platform side of things, however this project is wholly outside of that, I feel the need to pursue something I’m interested in. I work with the RabbitMQ team and a member of the AMQP Working Group.

Share/Save

Installing Erlang and RabbitMQ on RedHat

I am setting up a thin-provisioned vm running RedHat to host erlang and RabbitMQ for our QA team to test my code. Having not done anything on RedHat (just Ubuntu) for a long time I had forgotton everything and yet it was still incredibly simple:

Find the latest release – this was at the time of my install. The path will give you the right idea for the current version:

yum install erlang

For some reason yum has a pretty old version so you may want to manually install it. Choose your RabbitMQ server version -  2.1.0 was the current for this install.

wget http://www.rabbitmq.com/releases/rabbitmq-server/v2.1.0/rabbitmq-server-2.1.0-1.noarch.rpm

rpm –install rabbitmq-server-2.0.0-1.noarch.rpm

Then I verified in a few directories that RabbitMQ was installed, and ran

/sbin/service rabbitmq-server start

Verify that your RabbitMQ node is running:

rabbitmqctl status

If you have no nodes up rabbitmqctl will run but tell you no nodes are up to report status on. Simply restart at least one node.

If you want RabbitMQ to start after everything else on startup/reboot do:

ln -s /etc/rc3.d/S99rabbitmq-server ../init.d/rabbitmq-server

Share/Save

RabbitMQ and Erlang Intallation for Mac OSX

I’ve been a linux developer for years so I was all thumbs having to look up everything when setting up a new dev environment on a mac. Here’s some tips for setting up a local RabbitMQ server to play with (i.e. not using macports locally, not the EC2 install etc):

Requirements

  1. Apple XCode to compile Erlang with gcc. The XCode download could not take longer. Start it, go build an enterprise app in ROO, deploy it to the cloud. When you come back it may have completed.
  2. wget from http://ftp.gnu.org/pub/gnu/wget
  1. tar -xzf wget-{version}.tar.gz
  2. cd wget{version}
  3. ./configure
  4. make
  5. sudo make install

Install and build Erlang

First, Check for the latest Erlang GA Release and note the version.

  1. cd to the dir you wish to install into
  2. wget http://erlang.org/download/otp_src_{version}.tar.gz
  3. tar xzvf otp_src_{version}.tar.gz
  4. cd otp_src_{version}
  5. NOTE: run ./configure –help to see what opts you want to run with
  6. ./configure
  7. make
  8. sudo make install

Install RabbitMQ Server

First check the latest version of RabbitMQ Server and note the filename.

  1. wget http://www.rabbitmq.com/releases/rabbitmq-server/v2.3.1/rabbitmq-server-generic-unix-{version}.tar.gz
  2. tar xzvf rabbitmq-server-generic-unix-{version}.tar.gz
  3. Complete the install and config from http://www.rabbitmq.com/install.html#generic-unix, making sure the logs, clustering, data and config dirs are set up
  4. Start RabbitMQ: run rabbit../sbin/rabbitmq-server

Infinitely easier on Ubuntu.

Share/Save

JMX and MBean Support With Spring

The context of this post is simply about how to use the Spring Framework to export your Spring-managed pojos for management and monitoring via JMX. Later I’ll post on using Hyperic, in the cloud, etc. First things first – as this is an update from a similar post of mine from ’08 or early ’09.

Let’s start by adding the spring jmx dependency, which will be something like this, depending on the repos you are using:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.core</artifactId>
<version>${spring.framework.version}</version>
</dependency>

Service Pojo

Now let’s set up some java classes for management. I have a business service that I want to monitor and a pojo to instrument.

@BusinessService
@ManagedResource(objectName = "bean:name=inventoryManager", description = "Inventory Service",
        log = true, logFile = "oms.log", currencyTimeLimit = 15, persistPolicy = "OnUpdate", persistPeriod = 200,
        persistLocation = "foo", persistName = "bar")
public class InventoryServiceImpl implements InventoryService {

    @Autowired private InventoryDao inventoryDao;

    @ManagedOperation(description = "Add two numbers")
    @ManagedOperationParameters({
            @ManagedOperationParameter(name = "x", description = "The first number"),
            @ManagedOperationParameter(name = "y", description = "The second number")})
    public int add(int x, int y) {
        return x + y;
    }

    @ManagedOperation(description = "Get inventory levels")
    @ManagedOperationParameters({@ManagedOperationParameter(name = "product", description = "The Product)})
    public long getInventoryLevel(Product product) {
        return getInventoryLevel(product.getSkew());
    }
}

First, let’s peak into my @BusinessService annotation in case you are wondering:

@Transactional
@Service
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface BusinessService {
}

Annotating any of my service layer pojo’s makes them both transactional and with an instance created in the Spring context.

Entity Pojo

Now here is a simple pojo as an entity or javabean, what have you:

@ManagedResource(objectName = "bean:name=myPojoEntity", description = "My Managed Bean", log = true,
        logFile = "oms.log", currencyTimeLimit = 15, persistPolicy = "OnUpdate", persistPeriod = 200,
        persistLocation = "foo", persistName = "bar")
public class MyPojo {

    private long somethingToTuneInRuntime;

    /* Creates a writeable attribute for managing */
    @ManagedAttribute(description = "Tunable In Runtime Attribute",
            currencyTimeLimit = 20,
            defaultValue = "bar",
            persistPolicy = "OnUpdate")
    public void setSomethingToTuneInRuntime(long value) {
        this.somethingToTuneInRuntime = value;
    }

    @ManagedAttribute(defaultValue = "foo", persistPeriod = 300)
    public String getSomethingToTuneInRuntime() {
        return somethingToTuneInRuntime;
    }
}

Spring Config

Now let’s configure Spring to autoregister our pojos to export and manage/monitor:
Create a jmx-context.xml file in your WEB-INF/* dir

Add: <context:mbean-export/>

Activates default exporting of MBeans by detecting standard MBeans in the Spring
context as well as @ManagedResource annotations on Spring-defined beans.
Rather than defining an MBeanExporter bean, just provide this single element. I could walk you through a simple, simpler and simplest config of spring jmx but with annotational config in the simplest requirements, this is all you need to do to get up and running. If you need object naming in multiple vm situations, you can easily do that and other things too but, that’s out of scope for this post ;)

Share/Save

Future Posts: Esper, RabbitMQ for Cloud Messaging

If I had more time I would add a few new posts on esper and rabbitmq for messaging in the cloud but I just got home from 2 weeks of coast-to-coast consulting and technology presentations. Pretty exhausting. I hope to have time to post on these and a few other fun technologies. I’ve got some code samples and tests I might post with that, plus some cools stuff on esper queries with Spring Integration.

Share/Save

Spring Sample App

I’ve been traveling a lot as a Senior Consultant with SpringSource and many of the engineers that have been at my private and public engagements on core spring and enterprise integration with spring have requested a copy of my sample app that I use to demonstrate configurations, run demos and tests, etc.

This week I’m finally getting it finished and available to check out from svn. I’ve had a project set up in one of our public-facing repositories, the code will be available next week. Shoot me an email via my SpringSource address – attendees have that email, or find me on linkedin.com

May 10 I officially move into engineering!

Share/Save