Saturday, September 26, 2009

VPNC & Linux: "vpnc: no response from target" and host lookup

In trying to use VPNC on my desktop, running Arch Linx at home to VPN to work, I encountered two problems. The first is the popular vpnc: no response from target problem and the second involved determining the name of my host once I was connected.

I installed VPNC using Arch's package manager:

$ pacman -Sy vpnc
Then I copied a configuration file from my laptop running Ubuntu 9.04 to /etc/vpnc/mycompany.conf (I'm omitting the gateway address of course and replacing it with a series of X's):
IPSec ID 3des
IPSec gateway XXX.XXX.XX.X
IPSec secret 3des
Xauth username prystasj
NAT Traversal Mode cisco-udp

This worked fine for a while, but eventually I was unable to connect with the popular vpnc: no response from target exception. After some googling, I was added the following two IKE directives and a Local directive for the port:

IPSec ID 3des
IPSec gateway XXX.XXX.XX.X
IPSec secret 3des
Xauth username prystasj
IKE Authmode psk
IKE DH Group dh2
NAT Traversal Mode cisco-udp
Local Port 10000
Then I was back in business When viewing similar postings about the no response error, it was noted the NAT directive was one that was also commonly needed.

Hopefully the above can help some with similar connection issues. Now for the second problem. After my VPN connection was created, a Java application I needed to run required to lookup the hostname, was failing with a java.net.UnknownHostException.

To confirm, I ran nslookup with my hostname and received an error at the end of the output:

$ nslookup myhost
Server: 123.456.78.999
Address: 123.456.78.999#11

** server can't find myhost: NXDOMAIN
The answer it turns out (for me at least) lied in /etc/resolv.conf. When running VPNC the file was replaced with the contents similar to the following:
#@VPNC_GENERATED@ -- this file is generated by vpnc
# and will be overwritten by vpnc
# as long as the above mark is intact
# Generated by dhcpcd from eth0
# /etc/resolv.conf.head can replace this line
domain gateway.2wire.net
nameserver 132.174.47.100
nameserver 132.174.47.101
# /etc/resolv.conf.tail can replace this line
I needed to add the address of my server as a nameserver taking the address from the output of nslookup:
domain gateway.2wire.net
nameserver 123.456.78.999
nameserver 132.174.47.100
nameserver 132.174.47.101
Now both nslookup, and therefore my Java application, can resolve the hostname:
$ nslookup myhost
Server: 123.456.78.999
Address: 123.456.78.999#11

Name: myhost.somegateway.someprovider.net
Address: 321.654.87.999

Unfortunately, I can no longer reach any hosts on the network I'm now connected to. I need to do some more research on resolving it seems. I also tried a search directive. I followed the advice here for dnsmasq: Setup of OpenDNS and dnsmasq (on Arch Linux).

Now the Java application cited it could not find a host with name D5BMHS91, so I had to edit my /etc/hosts as such:

# /etc/hosts: static lookup table for host names
127.0.0.1 localhost myhost D5BMHS91

Notes: This was all done on Arch Linx 2009.08. In order to get nslookup to work, I had to install dnsutils.

$ sudo pacman -Sy dnsutils

Sunday, September 6, 2009

Groovy & XML: Retrieve the Namespace of Nested Elements

Recently, I need to retrieve the default namespace from an incoming message such as:

<message xmlns="Message" a="1" b="2">
<request>
<text xmlns="Text" a="1">ok</text>
</request>
</message>

With a message like the above, I want to retrieve the namspace Text from the text element.

One method I was able to leverage was using Groovy's DOMBuilder and DOMCategory to read the message and retrieve the namespace:

import groovy.xml.DOMBuilder
import groovy.xml.dom.DOMCategory

def xml = """<message xmlns="Message" a="1" b="2">
<request>
<text xmlns="Text" a="1">ok</text>
</request>
</message>"""

def reader = new StringReader(xml)
def doc = DOMBuilder.parse(reader)
def root = doc.documentElement
def ns

use(DOMCategory) {
ns = root['request']['text'].'@xmlns'[0]
}
println "ns=$ns"

Output:

ns=Text

Omitting the lookup of the first element, we would get a list:

ns = root['request']['text'].'@xmlns'

Output:

ns=["Text"]

This could be used to get a list of all attribute value for an element.

Another method is to use XMLParser:

def doc = new XmlParser(false, false).parseText(xml)
def ns = doc.'request'.'text'.'@xmlns'
Or XMLSlurper:
def doc = new XmlSlurper(false, false).parseText(xml)
def ns = doc.'request'.'text'.'@xmlns'

Both methods requiring making the XML reader namespace unaware with the following constructors:

XmlSlurper(boolean validating, boolean namespaceAware)
XmlParser(boolean validating, boolean namespaceAware)

I'm sure there are plenty of other methods to do the same, if you have one please feel free to leave a comment.

Tuesday, September 1, 2009

Mule: Using JiBX in Mule

Below I'd like to share my attempt to use JiBX inside of Mule to transform incoming XML message into a domain object and back again on the way out. In short, I created a request and response transformer that extended AbstractTransformer.

To start, I had the following domain objects:

   class Person {
String firstName
String lastName
Address addresss
}

class Address {
String city
String state
}

And a sample XML message where a Person has an Address:

  <person>
<firstname>George</firstname>
<lastname>Costanza</lastname>
<address>
<city>Queens</city>
<state>NY</state>
</address>
</person>

The binding file I used to test out my transformers:

  <?xml version="1.0" encoding="UTF-8"?>
<binding>
<mapping name="person" class="Person">
<value name="firstname" field="firstName"/>
<value name="lastname" field="lastName"/>
<structure name="address" field="address" class="Address">
<value name="city" field="city" />
<value name="state" field="state" />
</structure>
</mapping>
</binding>

Ok, now to something more interesting with that out of the way... the transformer to turn an incoming XML message to a Person object to use in my service component. Below is one representation of the transformer in Groovy with the types releated to JiBX declared:

class JibxXmlToObject extends AbstractJibxTransformer {
protected Object doTransform(Object src, String encoding) throws TransformerException {
def transformedObject
try {
Reader reader = new StringReader((String) src)
IBindingFactory factory = BindingDirectory.getFactory(Class.forName(getTargetClassName()))
IUnmarshallingContext context = factory.createUnmarshallingContext()
transformedObject = context.unmarshalDocument(reader)
}
catch(e) {
throw new TransformerException(this, e)
}

return transformedObject
}
}

To test out my transformer originally, I originally hard-coded the target class name:

  IBindingFactory factory = BindingDirectory.getFactory(Class.forName("org.prystasj.Person"))

In my Mule configuration, I will be declaring it however. If the transformer was a Java class, I might have to have getters and setters to allow for the target class name to be injected. Below is my declaration of the transformer as a custom transformer:

  <custom-transformer name="XmlToPerson" class="org.prystasj.transformers.JibxXmlToObject">
<spring:property name="targetClass" value="org.prystasj.Person"/>
</custom-transformer>
  <file:endpoint name="XmlInboundEndpoint"
  path="/tmp/input"
  pollingFrequency="3000"
  transformer-refs="XmlToPerson"/>

And here are the outgoing side of things, transforming a Person back to XML:
public class JibxObjectToXml extends AbstractJibxTransformer {
protected Object doTransform(Object src, String encoding) throws TransformerException {
String xml
try {
def writer = new StringWriter()
IBindingFactory factory = BindingDirectory.getFactory(Class.forName(getTargetClassName()))
IMarshallingContext context = factory.createMarshallingContext()
context.marshalDocument(src, encoding, null, writer)
xml = writer.toString()
} catch(e) {
throw new TransformerException(this, e)
}

return xml
}
}

And the corresponding Mule configuration:

  <custom-transformer name="PersonToXml" class="org.prystasj.transformers.JibxObjectToXml">
<spring:property name="targetClass" value="org.prystasj.Person"/>
</custom-transformer>
  <file:endpoint name="XmlOutboundEndpoint"
path="/tmp/output"
pollingFrequency="3000"
responseTransformer-refs="PersonToXml"/>

Putting the pieces together with a service definition, this example would take a Person in XML and echo it back out in XML after performing both transforms:

  <model name="XmlPersonModel">
<service name="XmlInputService">
<inbound>
<file:inbound-endpoint ref="XmlInboundEndpoint"/>
</inbound>
<echo-component/>
<outbound>
<pass-through-router>
<file:outbound-endpoint ref="XmlOutboundEndpoint"/>
</pass-through-router>
</outbound>
</service>
</model>

A more useful service component could be used to manipulate the incoming person in some way.