Monday, October 29, 2012

Everest for Windows Phone 7–WCF Connector

Well, as I mentioned in my previous post, Everest is here for WP7. Currently we’re still sorting out some bugs but the first bit of code is available in the 1.1 branch on our public SVN.

So, what can you do with Everest for WP7? Well, pretty much anything you’d like to do with HL7v3. I made a sample application that will hit the MARC-HI client registry and shared health record to demonstrate how the WCF Connector works in the mobile version of Everest (it is slightly different than the full fledged desktop version).

We’re going to be making this app:

image

Create a simple Windows Phone 7 application in Visual Studio 2010 (like you normally would) and add these references to your project:

  • MARC.Everest.Phone.dll
  • MARC.Everest.Phone.Connectors.WCF.dll
  • MARC.Everest.Phone.Formatters.XML.ITS1.dll
  • MARC.Everest.Phone.Formatters.Datatypes.R1.dll
  • MARC.Everest.RMIM.CA.R020402.Phone.dll

First, we’ll need to create a ServiceReferences.ClientConfig file and set its build action to Content. In that file, we’ll configure the WCF client configuration (similar to the Everest desktop version):

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="hl7v3Binding" maxBufferSize="2147483647"
                    maxReceivedMessageSize="2147483647">
                    <security mode="None" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://cr.marc-hi.ca:8080/cr" binding="basicHttpBinding"
                bindingConfiguration="hl7v3Binding"
                contract="MARC.Everest.Connectors.WCF.Core.IConnectorContract" name="ClientRegistry" />
        <endpoint address="http://shr.marc-hi.ca:8080/shr" binding="basicHttpBinding"
            bindingConfiguration="hl7v3Binding"
            contract="MARC.Everest.Connectors.WCF.Core.IConnectorContract" name="SHR" />
      </client>
    </system.serviceModel>
</configuration>

Note that WCF for the phone platform only supports basicHttpBinding and customBinding (no wsHttpBinding so SOAP 1.2 will need adjustments).


Next, we’ll initialize two connectors: one for the client registry and one for the shared health record. Because of the way that the WCF connectors work on Silverlight mobile (async only) you’re going to be using BeginSend and EndSend methods so these methods are fields for the Main.xaml.cs class:

private WcfClientConnector m_clientRegistryConnector;
private WcfClientConnector m_sharedHealthRecordConnector;

Next, we’re going to need a shared reference to the resolved patient identity received from the client registry, this is done via another field:

private MARC.Everest.RMIM.CA.R020402.PRPA_MT101104CA.IdentifiedEntity m_patientIdentification;

Since the WCF client connector will be sending the message asynchronously, meaning the actual sending is done on a separate thread. When the result callback is executed, it will be in the context of the thread that sent the message and not the thread that the UI is running on, we need to use the dispatcher to update the UI. Let’s declare a delegate to perform the UI update:

delegate void MessageSentDelegate(IGraphable connector);

Now, we can initialize the WCF connectors on the main page. I’ve done this in the constructor after InitializeComponent() is executed (which is hackish, but this is a tutorial after all).

// Constructor
public MainPage()
{
     InitializeComponent();
    m_clientRegistryConnector = new WcfClientConnector("endpointname=ClientRegistry");
    m_clientRegistryConnector.Formatter = new XmlIts1Formatter() { ValidateConformance = false };
    m_clientRegistryConnector.Formatter.GraphAides.Add(new DatatypeFormatter());
    m_clientRegistryConnector.Open();
    m_sharedHealthRecordConnector = new WcfClientConnector("endpointname=SHR");
    m_sharedHealthRecordConnector.Formatter = new XmlIts1Formatter() { ValidateConformance = false };
    m_sharedHealthRecordConnector.Formatter.GraphAides.Add(new DatatypeFormatter());
    m_sharedHealthRecordConnector.Open();
    ResolveClientIdentifiers();
}

Our resolve client identifiers code will execute a client registry lookup to translate our local identifier (I’m using 000-123-456) and get additional information about the client (their name, address, etc.). Here is the code:

private void ResolveClientIdentifiers()
{
    PRPA_IN101103CA instance = new PRPA_IN101103CA(
        Guid.NewGuid(),
        DateTime.Now,
        ResponseMode.Immediate,
        PRPA_IN101103CA.GetInteractionId(),
        PRPA_IN101103CA.GetProfileId(),
        ProcessingID.Production,
        AcknowledgementCondition.Always,
        new MARC.Everest.RMIM.CA.R020402.MCCI_MT002200CA.Receiver(
            null,
            new MARC.Everest.RMIM.CA.R020402.MCCI_MT002200CA.Device2(
                new II("1.3.6.1.4.1.33349.3.1.1.2", "CR")
            )
        ),
        new MARC.Everest.RMIM.CA.R020402.MCCI_MT002200CA.Sender(
            new MARC.Everest.RMIM.CA.R020402.MCCI_MT002200CA.Device1(
                new II("1.3.6.1.4.1.33349.3.1.1.20.4", "MARC-W1-1")
            )
        ),
        new MARC.Everest.RMIM.CA.R020402.MFMI_MT700751CA.ControlActEvent<MARC.Everest.RMIM.CA.R020402.PRPA_MT101103CA.ParameterList>(
            Guid.NewGuid(),
            PRPA_IN101103CA.GetTriggerEvent(),
            new MARC.Everest.RMIM.CA.R020402.MFMI_MT700711CA.Author(
                DateTime.Now
            ),
            new MARC.Everest.RMIM.CA.R020402.QUQI_MT120008CA.QueryByParameter<MARC.Everest.RMIM.CA.R020402.PRPA_MT101103CA.ParameterList>(
                Guid.NewGuid(),
                new MARC.Everest.RMIM.CA.R020402.PRPA_MT101103CA.ParameterList()
                {
                    ClientId = new List<MARC.Everest.RMIM.CA.R020402.PRPA_MT101103CA.ClientId>() {
                        new MARC.Everest.RMIM.CA.R020402.PRPA_MT101103CA.ClientId(
                            new II("1.3.6.1.4.1.33349.3.1.3.12", "000-123-456")
                        )
                    }
                }
            )
        )
        {
            EffectiveTime = new IVL<TS>(DateTime.Now)
        }
    );
    instance.ProfileId[0].Extension = "R02.04.02";


    instance.controlActEvent.Author.SetAuthorPerson(new MARC.Everest.RMIM.CA.R020402.COCT_MT090502CA.AssignedEntity(
        new MARC.Everest.RMIM.CA.R020402.COCT_MT090102CA.Organization(
            new II("1.2.840.114350.1.13.99998.8734"),
            "Good Health Hospital"
        )
    ));
     var retVal = m_clientRegistryConnector.BeginSend(instance, this.CrConnectorCallback, null);
           

}


You will notice that the callback for the BeginSend method is a callback delegate CrConnectorCallback. This method will be executed on the thread that the message was processed on, and will use the Dispatcher object to update the UI:

private void CrConnectorCallback(IAsyncResult result)
{
           
    var sendResult = this.m_clientRegistryConnector.EndSend(result);
    var res = this.m_clientRegistryConnector.Receive(sendResult);
    this.Dispatcher.BeginInvoke(
            new MessageSentDelegate(this.MessageSentResult),
            new object[] { res.Structure });
           
}

This callback executes the MessageSendResult delegate (of type MessageSentDelegate that we created earlier). This updates the UI to include the patient’s name in the Application Text area.

private void MessageSentResult(IGraphable message)
{
     if(message is PRPA_IN101104CA)
    {
        var msg = message as PRPA_IN101104CA;
        if(msg.Acknowledgement.TypeCode != AcknowledgementType.ApplicationAcknowledgementAccept)
            return;
        var rreg = msg.controlActEvent.Subject[0].RegistrationEvent.Subject.registeredRole;
        this.m_patientIdentification = rreg;
        this.ApplicationTitle.Text = rreg.IdentifiedPerson.Name[0].ToString("{FAM}, {GIV}");
        ExecuteGetSummary();
    }
}

The result of this will be an app that, a few seconds after loading, will display the name of patient 000-123-456 in the application text bar.


image


In my next post, I’ll show you how to get the clinical summary using COMT_IN100000CA messages with query continuation (a very useful construct on the phone).

Saturday, October 27, 2012

Everest for Windows Phone 7.1

Here at the Everest team we’ve been so busy building the Java version of Everest (jEverest) that I haven’t had a chance to discuss another exciting Everest feature, Windows Phone 7 Silverlight libraries.

Basically we’ve done some cross-compiling in Visual Studio to remove the features of Everest that don’t work on the mobile platform, affected features are:

  1. Code generator formatter is disabled since the mobile platform doesn’t support code-dom or runtime code generation.
  2. The only connector supported is the WCF client connector
  3. XML ITS1 and Data Types R1 is currently only supported in the phone assemblies.

The current 1.1 unstable branch of Everest contains the Everest Phone code in the api.phone.sln code. As with all code in the unstable branch it is untested and your mileage may vary.

Ciao

Sunday, October 21, 2012

jEverest Bubbling Away

Well, it has been a busy week and the Everest team (mostly yours truly) has been busy churning the jEverest code. I’m pleased to report that there has been lots of progress made as far as core functionality goes.

We have a basic core library! That’s right there is a working copy of ca.marc.everest.jar containing about 85% of the HL7v3 data-types to Java. Not all the methods are fully fleshed out but structurally everything is there (no jUnit tests yet, volunteers?). The core library is at a point where it can be used with the latest unstable GPMR to generate Java classes for RMIMs.

Wait, did you say RMIMS? Why yes I did! Right now the latest unstable version of GPMR will generate RMIM jarchives for Canadian release 2.04.01, 2.04.02 and 2.04.03 (just trying out the NE2008 one right now). You can’t really do much with these until the other infrastructure components come online, namely the formatters and formatter utilities.

There is still a long way to go but for those wishing to see what Everest RMIM JARs will look like can download the latest unstable at: https://fisheye.marc-hi.ca/svn/Everest/branches/1.1/ (un: Guest). The copy of GPMR will render Java (after being compiled) and executing:

gpmr -c -r RIMBA_JA -o C:\java\r02.04.01  --quirks --rimbapi-gen-vocab=true --rimbapi-compile=true --optimize=true --combine=true --rimbapi-profileid=R02.04.01 --rimbapi-target-ns=ca.marc.everest.rmim.ca.r020401 --rimbapi-license=apache --rimbapi-org="Health Level Seven" --rimbapi-jdk="C:\Program Files (x86)\Java\jdk1.6.0_26" --rimbapi-jdoc=true  .\CA\R02.04.01\*.*mif

After a few minutes GPMR will spit out a complete Eclipse project (it will also attempt to compile the resulting files).


Source code for the core jEverest file can be found in the jEverest folder.

Wednesday, October 10, 2012

Java Everest (jEverest) Update

I was looking through some old Everest code on the trunk and 1.0 branch about a month ago and realized that the jEverest project had stalled. I was trying to think of a killer new feature for Everest 1.2 and I hadn’t realized the answer was staring me right in the face this whole time.

jEverest is a Java version of Everest which was intended to be completed by January of this year, however because of more pressing issues it was dropped in favour of other work (such as the Client Registry reference implementation and Shared Health Record implementations). But not anymore. We’ve made some really good progress on the datatypes and supporting classes and with our public SVN server you can take a look!

jEverest is in the 1.1 branch (1.2 development) of the Everest project on the server. So far we have completed a port of the majority of data types and some enhancements to the GPMR java renderer. Hopefully we’ll have something to demonstrate by HL7 WGM in January but I wouldn’t expect a release until later in 2013.

Anyone who has talked to me (in person) knows that I’m not the biggest fan of the Java platform (IMO C# and .NET is much better) however it is not nearly as terrible as I had remembered it. Java 1.7 does have some nice features (like strings in switch cases, finally!) however I do have some legitimate complaints about Java development (just observations, don’t want to start a war)

  1. Eclipse : Nice IDE, lots of features and bells and whistles however I’d much rather prefer an IDE which has less features but does them properly. For example:
    • Subclipse isn’t the best when you’re in the “Java perspective”, it simply wraps the SVN command line and places conflict markers directly in your code which I then have to resolve by “Right Click -> Open in Conflict Editor”. Why? Maybe I’m just used to VisualSVN.
    • Why are there two places to get Eclipse extensions? Some extensions I have to visit “Help -> Install New Software” and others “Help -> Eclipse Marketplace”. There should be one place to get extensions.
    • On the topic of extensions, my major complaint with Eclipse is the plethora of options. Everywhere I look, options options options! The context menus are huge and cluttered with options.
  2. Type Erasure : By far, this is my number one pet-peeve with Java. The fact that LIST<REAL> at runtime is indistinguishable from LIST<INT>. This causes lots of problems especially since the majority of data types use generics. Every time I implement a conversion method or validation method that really does need to know the type of a generic I can’t (or I have to use some hack)
  3. Closures : Believe it or not, this actually does matter in jEverest, especially when searching a collection. In Everest all collections have a Find() method (for example, to find all numbers in a list larger than a given number : for(int i = 0; i < 10; i++) numbers.FindAll(o=>o > i);). This can be a problem jEverest and to get around it I have to use a custom IPredicate / Predicate implementation. (contrast the previous Everest example with jEverest : for(int i=0; i<10; i++) numbers.findAll(new Predicate<INT>(i) { public bool match(INT c) { return c > this.getScopeValue(); } }); )

Overall these aren’t showstoppers, just require some clever trickery to make compatible solutions. The idea behind jEverest isn’t to be 100% code compatible with the .NET version, but to be a meaningful port of the functionality.

I’ll end on a positive note: Java enumerations are really cool and much better than C#/.NET. Being a class means that enumerations in Java can implement interfaces and I’ve taken full advantage of this for representing enumerated vocabularies (via IEnumeratedVocabulary) and hierarchical vocabularies (via IHierarchicEnumeratedVocabulary).

Keep your eyes open, jEverest is coming!

Thursday, August 23, 2012

Microsoft XDS.b Solution Accelerator Patient Identity Feed woes


Recently in the lab we setup the XDS.b solution accelerator (http://ihe.codeplex.com). Overall the software works however we've identified some problems with the HL7v3 messaging that is returned from the Registry actor.

A little backstory first: I've been asked to teach the Mohawk course for electronic health records, and part of this teaching is a series of hands-on labs which students use tools to communicate with standards based health software packages. One of these labs is an IHE XDS.b lab. One of the servers uses OpenXDS, and the Microsoft XDS.b solution accelerator was used to illustrate different software using the same standard.

Anyways, we have a PIX Manager reference implementation in our lab and I wanted to setup the manager to act as an identity source to the XDS registry (via ITI-44 messaging rather than the ITI-46 notification system). I had this working however I noticed that when I sent messages after 12 minutes past the hour Everest's TS type would throw an FormatException, usually these read:
The date "20124002154000" is not a recognized date/time

Which looked a little suspicious, after some digging in the XDS.b solution accelerator's code I found this line in the PatientIdentityFeedLogic.cs:

public static readonly string PATIENT_ACK_DATETIME_FORMAT = "yyyymmddhhmm";

Which needs to be corrected to :

public static readonly string PATIENT_ACK_DATETIME_FORMAT = "yyyyMMddhhmm";

Not sure how this was missed at connectathon however it was causing issues with the PIX manager. After the change, the XDS Registry works!

Anyways, to anyone thinking of deploying the Microsoft XDS.b solution accelerator should change this line prior to deployment. Additionally, use the instructions in the latest Sync package as these are correct.

Tuesday, August 21, 2012

Custom SOAP Headers


Wow, it has been awhile since I've been able to post any new content on this blog. It has been a very busy summer and I have to say that there are a few great projects that I've been working on and hope to release to the wild in a few weeks/months time.

In the meantime, I thought I'd post some code samples illustrating some of the new features of the WCF connector in the upcoming Everest 1.0.2 release (a minor update and bug-fix release). If you've ever had to use the WcfClientConnector or WcfServerConnector, you'll know that dealing with SOAP headers was … well… cumbersome. It required setting some odd properties and wasn't really thread safe. This has been addressed in the 1.0.1 release.

For this example, I'll show you how to read/write the WS-Addressing headers in a received message from the WCF connectors. First, to access the SOAP headers from a message received from a WcfServerConnector, you can simply access the Headers property on the WcfReceiveResult. The following code is written in the MessageAvailable event handler for a WcfServerConnector:

static void conn_MessageAvailable(object sender, MARC.Everest.Connectors.UnsolicitedDataEventArgs e)
{
     // Get the sending connector that raised the event
     var connector = sender as  WcfServerConnector;
     if (connector == null)
          throw new ArgumentException("Must be called from a WcfServerConnector", "sender");
     // Receive the message
     var receiveResult = connector.Receive() as WcfReceiveResult;

Pretty standard Everest stuff, next we'll emit the value of the WS-Addressing headers:

if (receiveResult.Headers != null){

     Console.WriteLine(receiveResult.Headers.To);

     Console.WriteLine(receiveResult.Headers.Action);

}

We can access the Headers array just like any other WCF Header, this applies to constructing the response as well. To construct the response, populate the ResponseHeaders on the receiveResult prior to call "Send()" on the server connector.

receiveResult.ResponseHeaders = new System.ServiceModel.Channels.MessageHeaders
(receiveResult.Headers.MessageVersion);
receiveResult.ResponseHeaders.Add(MessageHeader.CreateHeader("myHeader", "urn:my-ns:com", "Value"));
connector.Send(new MCCI_IN000002CA(), receiveResult);

This code will return the following soap header:

<tns:myHeader xmlns:tns="urn:my-ns:com">Value</tns:myHeader>

More complex headers can be added the same way you would add standard System.ServiceModel.Channel.MessageHeader objects. It is also possible to send message headers using the overridden Send() method on the WcfClientConnector:

var conn = new WcfClientConnector();
// trimmed
MessageHeaders messageHeaders = new System.ServiceModel.Channels.MessageHeaders(MessageVersion.Soap12);messageHeaders.Add(MessageHeader.CreateHeader("myHeader", "urn:my-ns:com", "Value"));
conn.Send(instance, messageHeaders);

As I said, this enhancement will be available in the 1.0.2 release of Everest, or is available in the 1.0 branch of the Everest SVN server (or the trunk if you're feeling adventurous and want to try Everest 1.2 features out as well).

Tuesday, May 22, 2012

Everest Clean-Up


It's been awhile since I've posted anything new on this blog and I must apologize, we've been very busy with various projects at the MARC-HI (now called MEDIC) and I haven't been able to post any updates.
One of the tasks that we've performed is a clean-up of the Everest source code, a migration to SVN, and a new roadmap for Everest features.

Clean-up of Source Code

The Everest source code has undergone some clean-up to facilitate the migration to SVN. This includes better documentation on the source code itself, clearer versioning (see roadmap) and some general enhancements to the way things are done in the Everest Framework.

Public SVN Access

The Everest source code is now publicly available via SVN at https://fisheye.marc-hi.ca/svn/Everest. Read only guest access is provided via the "Guest" account, patches can be submitted via the forums or e-mailed to an Everest team member.
The structure of the SVN repository is as follows:
/branches/1.0 – The branch from which the Everest 1.0 release was built
/branches/1.1 – The unstable "feature" branch for the 1.2 release of Everest
/trunk – Stable development trunk.
This branching structure may seem odd but we do have some rationale for structuring the repository like this. The development branches (odd numbers) are not guaranteed to compile or pass unit tests and are where we do the majority of our work on the main roadmap, whereas the trunk is always guaranteed to compile and pass regression tests and only includes new features that are stable.

New Versioning Scheme

The new Everest versioning scheme is as follows:
Major.Minor.Patch
Where Major is the major version (currently the 1.0 series) which are guaranteed to be backwards compatible with previous versions. Minor version numbers are revision or releases which introduce new functionality to the framework. Odd minor version numbers denote a development version whereas even numbers are releases (for example 1.1 is the development branch for 1.2 and 1.3 for 1.4, etc.).
Patches are normally used for tags and represent a collection of bug fixes for the framework components.
The team hopes that these changes will make Everest clearer and will open the gateway to encourage new developers to work on the framework. We're working on a methodology for allowing public commits to our repositories however this will most likely not be completed for quite some time.

Thursday, May 17, 2012

Everest in WCF vs. WCF in Everest

The connector architecture in the Everest framework is designed to be consistent regardless of the underlying transport. The four patterns provided by the connectors in Everest (Listen/Wait, Listen/Wait/Respond, Send and Send/Receive) provide common patterns for communicating on a variety of transports including queues, http, files and others.

When it comes to communicating or hosting services that respond using the WCF framework, the current Everest connector pattern is implemented in the form of a WcfServerConnector and WcfClientConnector. While this is great for consistency with the rest of the Everest framework it is awkward for developers who are familiar with WCF. In this manner of speaking WCF is used within Everest. In order to be truly easy to use, we needed to make Everest in WCF.
The current development branch of Everest (1.1) includes this functionality. Consider the process of receiving a message on the WCF connector, the function looks something like this:

/// <summary>
/// Message is available
/// </summary>
static void connector_MessageAvailable(object sender, MARC.Everest.Connectors.UnsolicitedDataEventArgs e)
{

    var connector = sender as IListenWaitRespondConnector;
    var receiveResult = connector.Receive();

    // Determine the type of interaction
    if (receiveResult.Structure is PRPA_IN201305UV02)
        ; // Do something here
    if (receiveResult.Structure is PRPA_IN201307UV02)
        ; // Do something here

    connector.Send(transactionResult, receiveResult);
}

Which makes sense from an Everest connectors point of view, however it is quite awkward to a typical WCF developer. In the new Everest framework version we can use the familiar WCF pattern as illustrated below:
[EverestSerializerFormat(Formatter = typeof(XmlIts1Formatter), GraphAide = typeof(DatatypeFormatter), ValidateConformance = false)]
[ServiceContract(Namespace="urn:hl7-org:v3")]
public interface IServiceContract
{
    /// <summary>
    /// Do something
    /// </summary>
    [OperationContract(Action="*")]
    IGraphable Anything(IGraphable request);

}
public class ServiceBehavior : IServiceContract
{

    #region IServiceContract Members

    /// <summary>
    /// Default message
    /// </summary>
    /// <returns></returns>
    public IGraphable Anything(IGraphable request)
    {
     
         // Determine the type of interaction
       if (request is PRPA_IN201305UV02)
          ; // Do something here
         if (request is PRPA_IN201307UV02)
          ; // Do something here
                    
        return transactionResult;        
    }

    #endregion
}

The EverestSerializerFormat attribute is very similar in functionality to the XmlSerializerFormat attribute and instructs the WCF layer to use Everest as the serialization engine rather than the built-in XML or data contract serializer.

Alternatively, developers can now piggy-back on the other WCF services to classify operations that are to be executed:
[EverestSerializerFormat(Formatter = typeof(XmlIts1Formatter), GraphAide = typeof(DatatypeFormatter), ValidateConformance = false)]
[ServiceContract(Namespace="urn:hl7-org:v3")]
public interface IServiceContract
{
    /// <summary>
    /// Handle PRPA_IN201305UV02
    /// </summary>
    [OperationContract(Action="PRPA_IN201305UV02")]
    PRPA_IN201306UV02 DoSomething(PRPA_IN201305UV02 request);

    /// <summary>
    /// Handle PRPA_IN201307UV02
    /// </summary>
    [OperationContract(Action = "PRPA_IN201307UV02")]
    PRPA_IN201308UV02 DoSomethingB(PRPA_IN201307UV02 request);

}

One limitation of using the EverestSerializerFormat attribute is the lack of access to validation errors and the result details.

Sunday, May 13, 2012

Everest Developer’s Handbook Available


One of the big projects that I've been working on over the past year is the creation of an in-depth guide to the Everest framework intended to be used by developers. I'm happy to announce "The Official Advanced Everest Developer's Handbook" is now available for purchase at lulu.com in both e-Book and Hardcover editions. As part of the launch, I am providing the e-Book free of charge and a 25% discount on the beautiful hardcover version for the month of May 2012.
This handbook is an in-depth look at the Everest Framework components and is intended to document how the Everest Framework implements various HL7v3 constructs and includes:
  • Over 100 examples of using various Everest Framework components
  • In-depth documentation about the Everest Data Types library
  • Documentation about the GPMR tooling and generating new RMIM assemblies
  • Documentation about advanced concepts of the framework such as attributes, utility classes and writing custom formatters and connectors.
Proceeds from the sales of the books are used to fund further enhancements to the Everest Framework at Mohawk College.
"The Official Advanced Everest Developer's Handbook (Hardcover)"

"The Official Advanced Everest Developer's Handbook (e-Book)"

Finally, a shout goes out to Ken Wong, a Mohawk graduate who donated some of his free time in designing the Cover and first page artwork. Obviously the art pays homage to the "Advanced Dungeons and Dragons" books released in the early 1980's.

Thursday, February 23, 2012

Everest 1.0 Is Here!

It has been a long journey, but the Everest Framework 1.0 release is now available at the MARC-HI Technology Exchange (http://everest.marc-hi.ca). There are a multitude of new features and usability enhancements include:

  • Support for NE2010, NE2011 and CDAr2 (Though only base versions of NE2010 and CDAr2 are included)
  • Formatters available for Data Types R2 (ISO21090:2009)
  • A new GPMR Wizard which makes turning MIFs into DLLs much easier
  • Changes in the way that GraphAides are added to formatters
  • Improvements in formatter error detail reporting

The next version on our roadmap is 1.5 slated for a 2013 release. Features so far include:

  • A JSON ITS Formatter
  • A REST based connector
  • Improvements to way that IListenWaitConnector and IListenWaitRespondConnector implementations raise notifications of messages received
  • JavaScript renderer for GPMR (output JS files that can be used to construct JSON objects using the JSON ITS)

The whole Everest team hopes that you enjoy the new version of Everest. Please feel free to leave comments on our forums (http://te.marc-hi.ca/forums) or submit any issues you encounter.