All the little references when you copy an eclipse project

January 14, 2010 on 10:50 pm | In eclipse | No Comments

Okay, maybe I’m not supposed to copy eclipse projects this way, but I simply wanted to make a copy of an eclipse project that had already been appropriately configured to include a number of libraries, etc., so that I didn’t have to go through all that config again. Seems like it should work, intuitively, and I guess we’re close, but there were a few tweaks I had to make by hand to get everything up and running the way I wanted.

Brief overview of my eclipse environment and project:

  • I am running eclipse V3.4.2 with WTP (and a couple other plugins that are inconsequential)
  • I’ve configured a Tomcat server so that I can run from within eclipse - i.e. Run As…->Run on Server
  • My project is a Dynamic Web Project

First thing I do after copying the project from, say, “MyProject” to “MyProject2″ is right click on the project, select Properties, go to Web Project Settings and update the Context Root; I want my new service to run at the URL …/services/MyProject2 instead of …/services/MyProject so I set the context root to MyProject2. I do a Project->Clean and then build the project and all looks fine. When I right-click Run As->Run on Server, select my Tomcat Server, click Next, here is the rub: Instead of showing MyProject2 in the list of configured projects I see MyProject listed twice. Turns out that I can select one of them and click the Remove All button, continue with the deployment (even with the old project name there) and everything runs on Tomcat as you would expect - the server responds to requests at url …/services/MyProject2.

So the question is, why isn’t the new project name picked up in the right places? I believe it is because a key settings file is written at project creation time via the wtp plugins, and writes the project name into that file, but when I created the project via a copy of the old, eclipse does not update that file. I found the file, but try as I might I cannot find a config page anywhere that allows me to update it - I guess this is not too surprising as, in theory, this is just bound to the eclipse project name and it would be confusing for users to diverge from that naming convention (certainly is confusing me).

The solution:

The file is the org.eclipse.wst.common.component file that is in the / /.settings directory. Close eclipse, open that file (it’s an XML file) and update the line that reads:


<wb-module deploy-name="MyProject">

to


<wb-module deploy-name="MyProject2">

and start eclipse. At this point I had to do another Project->Clean and build (else the context root for the web project was a mess) and then the last thing you need to do is clean the Tomcat work directory by right clicking on the server in the “Servers” tab and selecting Clean Tomcat Work Directory… Now, try running the app again via Run As->Run on Server and when you’ve selected the server and clicked Next you will see both MyProject and MyProject2 in the Configured Projects list - not to worry, the MyProject is just a left over reference from the last time you ran the old project and can be removed by selecting and clicking Remove All.

And now you’ve managed to update what I believe is the last reference to the old project name from your new project.

Basic Tutorial in Open eHealth IPF V2.0

November 10, 2009 on 4:46 pm | In Uncategorized | 1 Comment

I’ve just upgraded to V2.0 and to verify my install (really just checking my eclipse config for IPF) wanted to do a quick run of the basic tutorial. The first part of it (before extending it to set up an HTTP endpoint) was fine but there is a documentation bug for the latter part of the tutorial. The code shown in the tutorial that needs to be added to the SampleModelExtension.groovy file is missing an import; the file should be as follows:


package org.openehealth.tutorial
  
import org.apache.camel.model.ProcessorDefinition
import org.apache.camel.Exchange
    
class SampleModelExtension {
  
  static extensions = {
    ProcessorDefinition.metaClass.reverse = {
      delegate.transmogrify { it.reverse() }
    }
  
    ProcessorDefinition.metaClass.setFileHeaderFrom = { String sourceHeader ->
      delegate.setHeader(Exchange.FILE_NAME) { exchange ->
        def destination = exchange.in.headers."$sourceHeader"
        destination ? "${destination}.txt" : 'default.txt'
      }
    }
  }
}

Threw me for a bit of a loop because the camel javadocs are still describing the pre-camel-v2.0 Exchange interface which doesn’t include a FILE_NAME field.

Now I just have to find the time to figure out how to file doc bugs for IPF and Camel…

Open eHealth IPF - Getting the HL7 Tutorial Running (in version 1.7 of the IPF)

October 30, 2009 on 7:18 pm | In Uncategorized | No Comments

The Open eHealth Integration Platform is pretty darn cool. In addition to enhancements that serve the healthcare domain, it also extends Camel with a great number of features that are of general value, including a Groovy based DSL that supports the likes of closures (!!) and more. I’m liking it.

I’ve been looking at the available tutorials and didn’t get too, too far in before I hit a snag - in the third tutorial on the page, the HL7 Processing tutorial. The solution is very, very simple, and is given at the very end of this post, though finding the solution took me on a very instructive tour through the platform and a bunch of embedded packages. Fortunately, I had the benefit of time (the boys went to my son’s homecoming game last night) and absorbed a lot on the scenic route. Come along…

Following the tutorial instructions to the letter resulted in an error when I tried to run it (unit testing run either from within eclipse or by running mvn test at the command line):


SEVERE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@3bfc47] to prepare test instance [org.openehealth.tutorial.SampleRouteTest@2f996f]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:201)
...
[snip - a big stack trace with some cascading "Caused by:..." messages the last of which was the root cause]
...
Caused by: ca.uhn.hl7v2.HL7Exception: No map found for version 2.2. Only the following are available: [2.5, 2.3.1, 2.4, 2.6, 2.1, 2.5.1, 2.0D, 2.0, 2.3, 2.2]
at ca.uhn.hl7v2.parser.Parser.getMessageStructureForEvent(Parser.java:352)
...
[snip - a bunch more stack trace]

This error was getting thrown at bean instantiation time - the init method for the validationContext was failing. Of course, this error message is puzzling in two respects. First, most obviously, an error message that says “nothing available for x, only x, y and z are available” is rather contradictory. Second, when we look into the code for initialization of the validationContext we see that what we are doing is starting with a DefaultValidationContext and then we fill it in with the rules that are defined in the beans declared in the context.xml file. The DefaultValidationContext has a map, initially empty, from the HL7v2 versions (i.e. 2.1, 2.2, etc.) to the set of rules that apply to that version. Put that together with the error message above and we are easily mislead into thinking the system is complaining about some problem with the ruleMap in the DefaultValidationContext. Yes, mislead. This is NOT the map that is causing the problem.

What happens at bean initialization time starts out exactly as I describe in the previous paragraph - the validationContext bean is instantiated and during initialization a DefaultValidationContext is created at the rules specified in the context.xml file are added. As the rules are added the forContext Groovy method is called, a RuleBuilder is instantiated and the forVersion method is called on it - that is, the rules are basically parsed (more on this in a moment). The rules in the defaultTypeRules are not a problem and are loaded without issue. The difference between these and myCustomRules, which are not loading, is that the custom rules we’ve defined are using the abstractSyntax method (those in the defaultTypeRules are specifying rules using different approaches).

And here is the key…

What happens when you define a rule using abstractSyntax is that the rule is validated against the abstractsyntax of the designated HL7 message version. That’s right, the IPF is doing a bunch of work here to make sure you’ve specified rules that are relevant against the version of HL7v2 that you are targeting. So, for example, if you tried to define a rule against an ADT_A25 message and you targeted it forVersion(’2.2′), you’re cool. If however you target it forVersion(’2.1′) then the rule itself won’t validate because version 2.1 only has ADT messages up through ADT_A24. And it even does validation into the message formats. This is a huge value add, it’s a point of model governance that I wasn’t necessarily expecting to have in IPF.

So, back to the error message. The exception is thrown in ca.uhn.hl7v2.parser.Parser.getMessageStructureForEvent, the Parser does, indeed, contain a map from version numbers to messageStructures and the exception occurs because, indeed, there is no entry for version 2.2 (or any other version number for that matter). The question then is from where and when are they supposed to have been loaded. We don’t have to look too far, the Parser class includes a method called loadMessageStructures() and looking at the code in there we see:


for (int i = 0; i < versions.length; i++) {
   String resource = "ca/uhn/hl7v2/parser/eventmap/" + versions[i] + ".properties";
   InputStream in = Parser.class.getClassLoader().getResourceAsStream(resource);
   ...

That is, for each version (the list is hardcoded in a class variable) load up the structure from a properties file with the right name. I knew then that this had to be a packaging issue, and, assuming the tutorial once worked as written, a result of some recent change. Digging through jars, this specifically had to do with HAPI libraries, and vaguely remembering seeing something about HAPI versions, here:

As of IPF 1.7-m3, the underlying HAPI library has been updated. The HL7 version-dependent classes have to be included separately.

was the solution.

All that is to say that the only thing you need to do beyond what is described in the tutorial is add the following lines in the dependencies section of the pom.xml:


<dependency>
    <groupid>ca.uhn.hapi</groupid>
    <artifactid>hapi-structures-v22</artifactid>
    <version>0.6</version>
</dependency>

Increasing VMware disk capacity

October 26, 2009 on 12:16 pm | In vmware | No Comments

There are several helpful articles out there, but I had to use a combination of two of them to get it done. There are two steps:

  1. You need to increase the size of the HD from VMware’s viewpoint.
  2. And (MAYBE) you will need to use tools of the guest OS (the OS of the image) to repartition things.

I found two resources on line that helped me with this:

I won’t rewrite what is in these two articles, rather just give you a bit of guidance…

The article on the vmware community addresses both of the two required steps. The issue I ran into is that what they described for step 1 wasn’t available for me. Instead, I used the method described on the Novell site to change the size from a VMware perspective and then I used the EASEUS Partition Manager (my guest OS is Windows XP) to repartition in the OS.

One more note, depending on the type of hard disk, you may not need to do step 2. After you have run step 1, boot up the image and check the properties of the harddisk in the running image - that’ll tell you if you need to do any partitioning. Also, if I remember correctly, step 1 reported that I needed to partition at the conclusion of it’s work.

Of course, MAKE SURE TO BACKUP your image before doing any of this.

BYOTP?

September 14, 2009 on 6:18 pm | In Uncategorized | No Comments

Seriously?

I was on a 4 hour flight today and was the first person in the lav. No TP. A search through the entire cabin turned up only the rolls already hanging in the other lavs. You must be joking! Isn’t TP as important to the flight as the snacks for purchase? I dare say even more?

And for those who will inevitably ask which airline… United. Not sure one is any better than the other these days. Thank goodness for travel restrictions and far fewer plane rides.

What happened to the FUSE->FUSE Project option in the eclipse plugin?

August 27, 2009 on 11:43 am | In eclipse, CXF, REST | No Comments

A colleague of mine was still running eclipse with an older version of the FUSE plugin - in particular 1.0.0. He had a single option under the New->Project->FUSE category called “FUSE Project”. Selecting this option created what was essentially a web services project (in particular we are using it for RESTful services) that had all of the libraries set up, etc.

When I installed the latest version of everything, following the instructions in the FUSE installation guide that option was gone. Under the FUSE category there are now three options that are all essentially Camel focused - EIPs and the like. I did some digging and found that creating a web services project set up for FUSE (Service Mix - CXF) is now done via project options shipped with the Eclipse Web Tools Platform. Here’s how it works:

Select File->New->Project and then under Web select Dynamic Web Project. Clicking “Next” presents the following dialog:

Creating CXF Project

Under the Configuration section select the CXF Web Services Project v2.5 option and that’s it. Exporting this project to a war includes all of the necessary jars. This does, of course, require that you have set your CXF runtime preferences appropriately. In Windows->Preferences:

Setting CXF Runtime Parameters

The only gotcha I ran into was that plugin installation order matters. It’s still not clear to me if and when WTP is included in Eclipse IDE for Java EE Developers - the WTP 3.1 Release page says it does with Galileo but I was constrained to using Ganymede for other plugin compatibility; installing Ganymede Eclipse IDE for Java EE Developers did NOT seem to include the WTP, at least not the CXF pieces. Assuming WTP has to be installed, and assuming I want to install the latest FUSE integration designer, you have to install WTP first. When I did the FUSE plugin first I had several problems, most notably there was no CXF 2.x Preferences option under the Web Services preferences (see screen shot above); this is an option that is added when you install the appropriate parts of the WTP.

UPDATE 1/22/2010:

I’ve just installed Galileo and while it does include WTP, it does not include the CXF portions. Go to the update site

http://download.eclipse.org/webtools/updates

and then expanding each of Web Tools Platform, Web Tools Platform SDK and Web Tools Platform Tests (optional) select the CXF pieces - there is one in each category.

Installing CXF tools with WTP

Getting Started with Tuscany - for version 1.5

July 12, 2009 on 9:16 pm | In Bug, Tuscany | No Comments

My javascript is really rusty.

I spent an embarrassingly long time this weekend trying to get the sample in the Getting Started with Tuscany guide working but it’s there now. I followed the instructions to the letter and when I ran the store application my catalog was empty. Didn’t take long to figure out that my catalog service was never getting called but it took me a lot longer to figure out why. Turns out that the current version of the guide is not quite correct for running with v1.5.

One of the things that you will find if you dig as deep as I did is that Tuscany creates a javascript file that reflects the services and bindings that it finds in the composite file. That javascript file, which is called store.js for this particular example (to correspond to store.composite), will include javascript functions for the bindings your composite uses (in this case, JSONrpc and Atom) and instantiates those clients for each of the services it finds in the .composite file. In version 1.3.2 of Tuscany those last lines in the store.js look like:


var referenceMap = new Object();
referenceMap.catalog = new JSONRpcClient("/Catalog").Service;
referenceMap.shoppingCart = new AtomClient("/ShoppingCart/Cart");
referenceMap.shoppingTotal = new JSONRpcClient("/Total").Service;
function Reference(name) {
    return referenceMap[name];
}

And as given in the guide the javascript in the store.html file includes:


//@Reference
var catalog = new Reference("catalog");
 
//@Reference
var shoppingCart = new Reference("shoppingCart");
 
//@Reference
var shoppingTotal = new Reference("shoppingTotal");

Well, with version 1.5 of Tuscany the last few lines of the store.js are different:


tuscany.sca.referenceMap = new Object();
tuscany.sca.referenceMap.catalog = new JSONRpcClient("/Catalog").Service;
tuscany.sca.referenceMap.shoppingCart = new AtomClient("/ShoppingCart/Cart");
tuscany.sca.referenceMap.shoppingTotal = new JSONRpcClient("/Total").Service;
tuscany.sca.Reference = function (name) {
   return tuscany.sca.referenceMap[name];
}

A variable name change. A simple update to the store.html file to replace the variable Reference with tuscany.sca.Reference and all was well.


//@Reference
var catalog = new tuscany.sca.Reference("catalog");
 
//@Reference
var shoppingCart = new tuscany.sca.Reference("shoppingCart");
 
//@Reference
var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");

If only I had remembered that this was javascript and not java and I would have spent more time in the sun this weekend. Ah well, the silver lining is that I dug deep enough that I understand a lot more about Tuscany now.

Atom extension for hierarchy

July 9, 2009 on 9:08 pm | In LinkedData, CMIS, Atom, Standards | 2 Comments

There has been a bit of a debate going on in CMIS on this topic and I’m interested in thoughts from members of the REST and/or Atom community so am posting a synopsis here. The CMIS mailing list is open to the public and you can see the most recent thread on the subject here and from there can find other postings if you are interested enough to dig that deep. I give a pretty thorough overview here if you don’t have the cycles to follow the links.

The subject at hand is how to represent a hierarchy of entities in atom. Atom, of course, has a feed and an entry but there is no mechanism for embedding a feed either in another feed, or embedding a feed inside of an entry. I’m not really looking for feedback here that questions whether hierarchical representations are a good idea or not – CMIS has made the decision that they need them – so assuming we are going to represent them, the question is, what is the best approach.

Over the last couple of months we’ve spoken with Nikunj Mehta who is the author of an I-D on In-lining Extensions for Atom that defines a mechanism that could be used for hierarchical arrangements by embedding representations as child elements to the atom link relation. Because the requirements driving the I-D and CMIS differ, and because it seems that the I-D will likely take a fair bit of time to reach consensus, the CMIS TC has decided to create their own extension with an intent to replace this with an applicable standard once one is available.

All of that context established, the CMIS TC has considered several options and has down-selected to two – those that we are calling option 3 and option 4 (options 1 and 2 already having been dismissed).

What we refer to as option 3 is one where a folder entry has a cmis:children element that contains multiple atom:entry elements. In outline form it looks like:


<atom:entry>
  <atom:title>Folder A</atom:title>
  ...
  <cmis:children>
    <atom:entry>
      <atom:title>Folder B</atom:title>
      ...
    </atom:entry>
    ... more atom entries ...
  </cmis:children>
</atom:entry>

What we refer to as option 4 is one where a folder entry has a cmis:children element that wraps an atom:feed element that then contains multiple atom:entry elements.


<atom:entry>
  <atom:title>Folder A</atom:title>
  ...
  <cmis:children>
    <atom:feed>
      ... a bunch of feed stuff ...
      <atom:entry>
        <atom:title>Folder B</atom:title>
        ...
      </atom:entry>
      ... more atom entries ...
    <atom:feed>
  </cmis:children>
</atom:entry>

Option 3 has at least two advantages over option 4:

  • Option 3 will have a smaller representation because it does not include the feed and the elements that are required of a feed (i.e. the “bunch of feed stuff” shown in option 4 above)
  • Option 3 results in a simpler server side implementation because the feed needn’t be created.

In spite of these advantages I believe that option 3 has one significant disadvantage over option 4, and that is that we fundamentally have two different representations for the same resource, requiring that client developers must have two implementations of a function depending on how the resource representation was retrieved. Let me explain with an example.

Suppose a client developer has written some code to display certain things about a children collection – they want to display the name of the collection, the last updated value, a list of the children and they want to have a button that allows the user to select this location as a target of a new item creation. This code executes against a feed retrieved via the URL to that child collection (URL could have been bookmarked for example). The pseudocode for this is something like:


void processCollectionResource(feed childrenResource) {
  String title = childrenResource.getTitle();
  Date lastModified = childrenResource.getUpdated();
  // get the URL of the link relation with rel=”self”
  URL postURL = childrenResource.getLinkURL(“self”);
  Iterate childrenResource.getEntries() {
    // so something with each child
    //      (this will be the same in both cases)
  }
  // do something with all of this – render, etc.
}

Now the client realizes they want to do the same thing but against a set of children that are embedded within a hierarchical representation. Let’s first look at the pseudocode for option 4.

There is code that has to parse the child collection out – it is something like the first line of:


feed childrenResource = folderResource.getChildren().getFeed();
processCollectionResource(childrenResource);

The processCollectionResource method can be used as is.

For option 3, I need to pass in the folder resource and start navigating from there, because some of the information I need is at the folder and some of it is in the cmis:children element. So I’d make a call something like:


processCollectionResourceEmbedded(folderResource);

And the new code to process this slightly different representation is:


void processCollectionResourceEmbedded(entry folderResource) {
  String title = folderResource.getTitle();
  Date lastModified = folderResource.getUpdated();
  // get the URL of the link relation with rel=”down”
  // NOTE!!!! that the code is less self contained here – self
  // is more direct than down
  URL postURL = folderResource.getLinkURL(“down”);
  Iterate folderResource.getChildren().getEntries() {
    // so something with each child
    //      (this will be the same in both cases)
  }
  // do something with all of this – render, etc.
}

At the root of this difference is that with option 4 we are treating the set of children as a full-fledged, stand alone resource. This allows us, for example, to have different metadata for the children collection as for the folder itself (the CMIS domain model doesn’t make this distinction, however, option 4 would allow for this which is goodness). The children resource representation is self-contained – I don’t have to go up to the containing folder to find out something about the collection. Option 3 doesn’t really treat the children resource as a complete resource - it depends on the folder resource to describe something about the children collection resource.

I’m sure it’s not lost on anyone that with option 3 we are creating a new, proprietary (to CMIS), feed-like container mechanism with the cmis:children element instead of using the standardized one that already exists. I don’t think that is a good idea.

Finally, and perhaps most subtle, is the fact that with option 3 we are really treating the document that is retrieved as the unit of importance, because we are requiring more than just the representation of the children collection in order to process it. I am extremely interested in seeing CMIS provide support for more than just the document web, pushing into support for the linked data web. Atom is designed to support it – I don’t want to loose that with a poorly designed extension to atom.

Sure, embedding a feed duplicates some of the values from the folder entry to the feed (for CMIS), but I think that is a reasonable trade for the simplicity and elegance that it offers the client.

Getting the Apache CXF Jax-RS Basic sample running

May 2, 2009 on 4:37 pm | In CXF, REST | No Comments

I did it in January - just came back to it today and could not remember what I did. Where is my memory? So for my benefit, and perhaps the benefit of others, I’m writing it down. There are hints in the README that ships with the sample, but it was far from step by step.

Of course, there are a number of different ways you can get this running - this is just one way.

My environment:

  • FUSE Services Framework (CXF) version 2.1.3.2
  • Eclipse 3.3.2

And here’s what you do.

  1. Start up Eclipse with a new or existing workspace and use the Java perspective.
  2. Create a new project by selecting File->New->Other… and then Java->Java Project from Exiting Ant Buildfile. Enter the name of the project, something like “Basic Jax-RS Sample”. Browse to {FUSE Install dir}/samples/jax_rs/basic/build.xml. Check the box that reads “Link to the buildfile in the file system” and click Finish. Note that this checkbox does NOT make a copy of the sample directory, nor does it create a separate build.xml, rather uses the one that is in the sample directory. This build file references another build file that is relative to the build.xml file so in order to use the build file without changes it must be invoked from that directory.

This is all you need to do to set the project up. Now you can run it. We are going to do so all inside of eclipse. First we’ll run the server part of the sample and use a browser to invoke the services - just reads. Then we’ll run both the server and a simple client application from within eclipse. Read on.

Running the Server and GETting resources

  1. Expand the Basic Jax-RS Sample project
  2. Right click on the build.xml file and select “Run As->Ant Build…” - be sure to to select the “Ant Build…” with the dot-dot-dot so you can select what you want to build and run.
  3. Now you can fetch some resources - note that a few are created for you when you run the server. Invoke a URL either http://localhost:9000/customerservice/customers/123 or http://localhost:9000/customerservice/orders/223/products/323. Notice in the code that customers, via the path “customers/{id}” and products, via the path “orders/{oid}/products/{pid}” are the only two resources that support GET.

Also notice that the server only stays up and running for 5 minutes by default - if you wish to lengthen this you can change the line of code in the Server.java file that reads:

Thread.sleep(5 * 60 * 1000);

And that’s it. You are running the application. If you want to test out some write operations…

Running the Server and a Client Application

Both the server and the client can be run from within eclipse.

  1. If your server is not running follow the steps outlined in the section above - basically do a Run As->And Build… and select the server.
  2. Now run the client by right-click on the build.xml, Run As->Ant Build… and this time select “client” (deselect “server”)
  3. You can see the results of the execution in the console pane. Customer number 123 was updated and a new customer was created and assigned an id of 124 by the server. In fact you can now invoke the URL http://localhost:9000/customerservice/customers/124 to see that new customer resource.

That’s it, the basics of getting the application up and running.

Wow!

November 5, 2008 on 1:52 pm | In world | No Comments

We did it!

Next Page »

Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds. Valid XHTML and CSS. ^Top^