Saturday, April 19, 2014

The Simplicity of Groovy and HTTP

Do you ever have the need to do some simple tasks in your IT environment? Maybe you need to run a few checks on some URL's and ensure that everything is copasetic (returning 200's). There are plenty of tools out there that can ping URL endpoints and give you feedback, but why put a tool in place when you can write a Groovy script in under 50 lines of code that is effective? My answer is a) I think writing Groovy is fun b) it can be simple enough that I would rather spend a little time and create something myself c) why bother with implementing a tool if it is not really needed?

The script is pretty straight forward and I first start with a few imports.
import java.net.HttpURLConnection
import groovy.transform.ToString

Then I define a simple class, Target, to hold some state for the URL endpoints we would like to query on. In the Target class exists the name property for identification purposes, the url property to hold our endpoint and finally the status property to hold the Target status. Pretty simple, right?
@ToString(includeNames=true)
class Target {
    def name
    def url
    def status
}

The ToString annotation is quite powerful as it makes the output of our class state nice and readable. It overrides the default String toString() {} method with a nice default. We could also override the method in the class and format the data however we would prefer. The next part of the script defines a list of new Target instances that we can iterate through and check the status of each URL.
def targetList = [
    new Target(name:"Google", url:"http://www.google.com"),
    new Target(name:"Amazon", url:"http://www.amazon.com"),
    new Target(name:"Oracle", url:"http://www.oracle.com"),
    new Target(name:"Axiomatic IT", url:"http://www.axiomaticit.com"),
    new Target(name:"Bad Endpoint", url:"http://www.asfakddddjh.com")
]

I put together some sample instances of Target with some good data and some bad data so we can make sure things are working as they are expected. The next block of Groovy iterates through the list of Target instances, attempts to connect to each URL, checks for the 200 response code, checks to ensure that data is returned when a 200 response code is returned, assigns the appropriate status to each Target instance, prints each Target using the toString() method provided by the @ToString annotation and finally disconnects the HttpURLConnection.
targetList.each { target ->

    def url = new URL(target.url)
    def huc
    
    try { 
        huc = url.openConnection()
        huc.requestMethod = "GET"
        huc.connect()

        if(huc.responseCode == 200) {
            def br = new BufferedReader(new InputStreamReader(huc.inputStream))
            if(br) {
                target.status = "Success"
            } else {
                target.status = "Failure"
            }
        }
    } catch (Exception e) {
        target.status = "Failure"
    }

    println target

    huc.disconnect()
}

Below, you can see an example of what the output looks like when I ran the script. The @ToString annotation is producing the format below by default for each Target instance. It just makes things pretty when we call println or log the value of a Target instance.
Target(name:Google, url:http://www.google.com, status:Success)
Target(name:Amazon, url:http://www.amazon.com, status:Success)
Target(name:Oracle, url:http://www.oracle.com, status:Success)
Target(name:Axiomatic IT, url:http://www.axiomaticit.com, status:Success)
Target(name:Bad Endpoint, url:http://www.asfakddddjh.com, status:Failure)

Groovy makes things pretty simple and in under 50 lines of code I have a simple script I can run to check the status of some Web site URL's. I can make things a bit fancier and have the list of Target instances populated from some external data source like a file or database. I could also check the data to ensure that the response is returning valid HTML or some other valid type of data format. The possibilities are there but for now, I have what I need without too much overhead.

Having Fun with Groovy and the Ternary Operator

Groovy is a great language to compliment your Java skills and to increase your productivity on the JVM. From time to time I work on some code and enjoy sharing its likeness here so I can ensure that a) I don't forget what I have done and b) encourage other developers who are interested in the technologies I find interesting. In this script, I have a model object, Policy, that would normally be fetched from a database or some flavor of Web service.
class Policy {
    def number
    def type
    def value
}

Next, I define a closure the expects a policy number as input. Using the ternary operator, we verify that a valid policy number has been provided. If a policy number is provided, the closure returns a new Policy with some default values. In a normal situation the second part of the ternary operator would make a call to access a database or call a Web service to return meaningful data rather than just return some static Policy object.
// static fetch method returns a default Policy or an empty Policy
def fetchPolicy = { policyNumber ->
    policyNumber ? new Policy(number:policyNumber, type:"Life", value:10000) : new Policy()
}

It is pretty straight forward. When the policy number is not null or not empty we get the static Policy object. If the policy number is null or an empty string we just return an empty Policy object. Here is the rest of script that does a few assertions on a null policy number, a valid policy number and a policy number which is an empty string.
def policyNumber

// policyNumber is a null value
policyNumber = null
def policy1 = fetchPolicy(policyNumber)

assert policy1.number == null
assert policy1.type == null
assert policy1.value == null

// policyNumber is a valid value
policyNumber = "123456"
def policy2 = fetchPolicy(policyNumber)

assert policy2.number == "123456"
assert policy2.type == "Life"
assert policy2.value == 10000

// policyNumber is an empty value
policyNumber = ""
def policy3 = fetchPolicy(policyNumber)

assert policy3.number == null
assert policy3.type == null
assert policy3.value == null

There is nothing too fancy with this script but you may have noticed that there are no null checks or empty string checks within the fetchPolicy closure. It may not be a big winner for every developer, but I think that these little nuances are what make Groovy a language all Java developers should have in their toolbox.

Friday, August 17, 2012

Hazelcast: Offline Systems Processing

Hazelcast offers many features to developers working with systems of all shapes and sizes. Hazelcast's implementations of distributed Queue and Map offer possibilities of running Web applications while operational systems are down for maintenance or unavailable. Here is an approach to solving such a problem with Hazelcast.

Let's start with our business model. We sell widgets online and through our call center. We also service order and customer related issues in our call center. Every evening, our widget product database is inaccessible because of some maintenance tasks. Here is one place where Hazelcast fits into the picture.

Before our maintenance window, we preload the widget product data into a Hazelcast distributed Map named "widgets". Each map entry has a key, which is our unique widget id, and a value, consisting of a Widget object. Now, our Web applications can access product data from our Hazelcast distributed Map "widgets", rather than relying on our product database.

When an order is created, Hazelcast's distributed Queue comes into play. The Web applications can submit an order and it will be passed into our "orders" distributed Queue. Here we can keep our orders ready and waiting until our database comes back online. We configure our Queue to be backed by a Map so our "orders" elements, consisting of Order objects, can be persisted in our intermediary storage before being processed when our target datastore comes off of maintenance mode.

A big part of this solution is to have a great services or middleware layer that can take on the burden of working with our distributed Maps and Queues. This will create a good abstraction of our backend datastore and distributed data from our Web applications. As a service oriented architecture is a common approach to abstracting a backend from Web applications, this solution does introduce some complexity into the services or middleware architecture.

Here is a high level diagram of the setup:



With a mature services layer, our call center and online applications can create orders, search through our widgets that exist in our "widgets" distributed Map and even verify and validate orders that are currently only in our distributed Queue "orders" or our Map that is backing our Queue. This type of solution does take some up front planning, but 24/7 business comes at a cost.

Wednesday, December 21, 2011

A Message Routing Groovy DSL

The other day I was discussing system integration with a friend and he mentioned something about creating a DSL (Domain Specific Language) for the many aspects of enterprise integration. I have limited experience with writing DSL's but I figured I would give it a shot. Inspired by this post on the Canoo blog and my friend's idea, I started hacking on GroovyConsole. Groovy is a great language for writing DSL's because of the language's features like closures and map based interface implementation. Plus, Groovy has the benefit of being fully compatible with Java and other Java based tools. What I want to do is create a DSL for writing rules for a hypothetical message routing engine. Here is my Message domain class and System enum:
import groovy.transform.TupleConstructor

enum System {
    bus, db2, iSeries, mySQL, oracle, postgre
}

@TupleConstructor
class Message {
    String payload
    System origination
    System destination
    
    String toString() {
        "${payload} from:${origination} to:${destination}"
    }
}

Here is what I think the DSL might look like:
route message to oracle, mySQL when origination eq db2

What I am saying is, route a message to oracle and mySQL systems when the message's origination is db2. I guess I really didn't need to explain that because the DSL is pretty self explanatory, right? Let's move on to see what else the DSL might look like:
route message to iSeries, oracle, mySQL when payload contains 'Hello'

Is there a need to explain what the previous statement is stating? If you have not caught on yet, it is saying route a message to the iSeries, oracle and mySQL systems when the message's payload contains the word 'Hello'. In each case, I would imagine creating a new Message for each system that will be put on a queue or sent to an endpoint to be processed. Here is the meat of the code that will implement the DSL I designed above:
import static System.*

messages = []

Above, we have the initialization of the list of messages that will be the result of our DSL statement. If the proper conditions are met, we are returned a list of new messages to send to other systems.
def payload = { Message message ->
    message.payload
}

def destination = { Message message ->
    message.destination
}

def origination = { Message message ->
    message.origination
}

The code above handles referencing each message property. The code below handles the keywords route, to, when, eq, neq and contains. It also handles each message instance and the array of System destinations, for example: iSeries, oracle, mySQL.
def route(Message message) {
    [to: { System[] destinations ->
        [when: { Closure clos ->
            [eq: { System system ->
                if(clos(message) == system)
                    destinations.each { messages << new Message(message.payload, message.origination, it) }
                messages
            },
            neq: { System system ->
                if(clos(message) != system)
                    destinations.each { messages << new Message(message.payload, message.origination, it) }
                messages
            },
            contains: { String string ->
                if(clos(message).contains(string))
                    destinations.each { messages << new Message(message.payload, message.origination, it) }
                messages
            }]
        }]
    }]
}

Below, is an example Message instance for testing the DSL.
message = new Message("Hello there!", db2, bus)

When I run my DSL statements from above, I see the list of messages created to be sent on to the other systems.
route message to oracle, mySQL when origination eq db2

Result: [Hello there! from:db2 to:oracle, Hello there! from:db2 to:mySQL]

The second example:
route message to iSeries, oracle, mySQL when payload contains 'Hello'

Result: [Hello there! from:db2 to:iSeries, Hello there! from:db2 to:oracle, Hello there! from:db2 to:mySQL]

I think this is very cool for my first attempt at a DSL with Groovy. I am sure I can clean up the code a bit (feedback is welcome) and this is really just scratching the surface of what we can do with Groovy and DSL's!

Tuesday, November 15, 2011

Issue with Dynamic Proxy in Java?

I created a simple Annotation, Report, the other day to handle some simple logging/reporting tasks. The intent is to create a simple way to annotate methods that should be logged or reported during invocation. Here is what the Annotation looks like:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
    String menu();
    String name();
    Platform system();
}
I have an interface, Menu, which all Menu implementations will implement:
public interface Menu {
 
    public void doSomething(String session);
}
Here is an example implementation of Menu, MyMenu, with a Report Annotation on the doSomething(...) method. Platform is an enum that describes whether or not to log/report to Oracle, SQL Server or both systems as in the case below:
public class MyMenu implements Menu {

    @Report(menu="AIT_MM", name="MyMenu", system=Platform.BOTH)
    public void doSomething(String session) {
        System.out.println("Doing some work!");
    }
}
Here is a block of code that creates a MyMenu implementation of Menu and a Proxy instance of Menu, and gets the "doSomething" method and checks whether or not the Report Annotation is present on the Method, m:
    Menu menu = new MyMenu();
    Menu menuProxy = 
        (Menu) Proxy.newProxyInstance(menu.getClass().getClassLoader(), menu.getClass().getInterfaces(), new MyLogger(menu));
 
    try {
        Method m = menuProxy.getClass().getMethod("doSomething", String.class);
        if(m.isAnnotationPresent(Report.class))
            System.out.println("Annotation is here!");
    } catch (Exception e) {
        e.printStackTrace();
    }
  
    try {
        Method m = menu.getClass().getMethod("doSomething", String.class);
        if(m.isAnnotationPresent(Report.class))
            System.out.println("Annotation is here!");
    } catch (Exception e) {
        e.printStackTrace();
    }
The statement
if(m.isAnnotationPresent(Report.class))
evaluates to true in the second try/catch block with the normal instance of MyMenu, menu but it evaluates to false in the first try/catch block with the proxy instance of MyMenu, menuProxy. The above code also includes a reference to a class, MyLogger, that implements InvocationHandler. This is where the evaluation of
if(m.isAnnotationPresent(Report.class))
is imperative because it completes my implementation goal. Inside the MyLogger class, I have implemented the
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
method from InvocationHandler like so:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if(method.isAnnotationPresent(Report.class)) {
        Report r = method.getAnnotation(Report.class);
        this.logMyPrompt((String) args[0], r.menu(), r.name(), r.system());
    }
    return method.invoke(delegate, args);
}
Just some strange things that I noticed when trying to do something cool with Java Annotations. Everything works if I put a Report Annotation on the Menu interface's doSomething(...) method declaration, but that solution does not allow me to have individual data related to each implementations' doSomething(...) method.