Tuesday, May 29, 2012

What's cooking in the EDT kitchen? - May 29

Once again, here is my weekly blog post letting you know what we're working on for the next version of EDT. Normally I post these on Mondays, but yesterday was the Memorial Day holiday in the US. In case you missed it, read last week's post.

As a reminder, I don't mention the things we do routinely, like fixing defects, answering questions on the forum, writing documentation, etc.

Here are last week's accomplishments:

IDE Usability
  • Continued work on "open declaration" (F3) in the editor for files in EGLARs
  • Improved the way a native type is displayed in the debugger's Variables view
Extensibility
  • The prototype for extensible validation is nearly complete
Language
  • Updated time, timestamp, and date formatting to match our specification
  • Added support for more datatypes in XML coming from JavaScript
  • Implemented the string(n) and bytes(n) types in JavaScript (this was already done in Java)
Other
  • Prepared for the test phase of 0.8.1 Milestone 2 by writing test scenarios and testcases
  • Investigated integration with new mobile technologies
  • Supported the 2012 IBM Rational EGL Programming contest, open to university students in China http://www.ibm.com/software/cn/rational/eglcontest/ (the page is in Chinese). We're excited to have 87 teams with 160 people from 28 universities involved in the contest! Awards will be presented at the Beijing Innovate conference in August. 
Matt

Tuesday, May 22, 2012

What's cooking in the EDT kitchen? - May 22

This is the latest weekly blog post designed to let you know what's being cooked up for the next version of EDT. Normally I post these on Mondays, but I was out sick yesterday (no, it wasn't the cheese-like substance in fridge). In case you missed it, read last week's post.

Last week we continued making progress toward our goals for EDT 0.8.1.  Here are the details:

IDE Usability
  • Add search capability to the Open Part dialog
  • Make a "library" entry in the EGL Path of an EGLAR for the built-in types
  • Implement "open declaration" (F3) in the editor for files in EGLARs
Extensibility
  • Prototype extensible validation
  • Refactored annotation generation
Language
  • Add support for more datatypes in XML coming from JavaScript
Other
  • Finished the test phase of 0.8.1 Milestone 1 with a success rate of 95%. We won't be posting a milestone driver for M1 since much of the work has been to refactor for extensibility and less new functions.We do plan to post a milestone driver for M2. If you really want the latest, you can get the nightly builds though they are often not as stable as milestone or release builds. 
  • Investigate integrating with new mobile technologies. 
  • Support the 2012 IBM Rational EGL Programming contest, open to university students in China http://www.ibm.com/software/cn/rational/eglcontest/ (the page is in Chinese). We're excited to have 87 teams with 160 people from 28 universities involved in the contest! Awards will be presented at the Beijing Innovate conference in August. 
Matt

Monday, May 14, 2012

What's cooking in the EDT kitchen? - May 14

This is the latest weekly blog post designed to let you know what's being cooked up for the next version of EDT.  In case you missed it, read last week's post.

Last week the EDT chefs served a few new dishes along with some old favorites.  (Also, I found a really old onion in the back of the refrigerator, and something that might be a new kind of cheese.)

Here's what's been happening:

IDE Usability
  • Update searching and indexing for EGLARs
  • Make a "library" entry in the EGL Path of an EGLAR for the built-in types
  • Implement a read-only editor for files in EGLARs
Extensibility
  • Prototype extensible validation
Language
  • Support for foreach loop on arrays
  • Add new bit-manipulation operators
Other
  • Wrote new tests, with hundreds of new variations, for the test phase of 0.8.1 Milestone 1, and began running the tests
  • Investigate integrating with new mobile technologies
  • Support the 2012 IBM Rational EGL Programming contest, open to university students in China http://www.ibm.com/software/cn/rational/eglcontest/ (the page is in Chinese)
Matt

Monday, May 7, 2012

What's cooking in the EDT kitchen? - May 7

This is the latest weekly blog post designed to let you know what's coming in the next version of EDT.  In case you missed it, read last week's post.

Here's what's been happening:


IDE Usability
  • Update searching and indexing for EGLARs
  • Implement a read-only editor for files in EGLARs
Extensibility
  • Prototype extensible validation
Language
  • Support for foreach loop on arrays
  • Support for 'super' (to access an overridden function or field, or a super-type's constructor)
  • Add syntax for new kinds of literals
  • Add new bit-manipulation operators
  • Update testcases after the latest language changes
Other
  • Investigate integrating with new mobile technologies
  • Support the 2012 IBM Rational EGL Programming contest, open to university students in China http://www.ibm.com/software/cn/rational/eglcontest/ (the page is in Chinese)
  • Prepare for the test phase of 0.8.1 Milestone 1
Matt

Saturday, May 5, 2012

Sharing data among services

Services often need to share data. There are many examples: like storing an IBMiConnection using the HttpSession to create a persistent host Job, or a login service that stores configuration information on the session so data services have access to the information without directly obtaining it from the Rich UI application. It may be obvious, but it's worth stating, for invocations to share the same session they must use the same session cookie and the services must be deployed to the same server cluster.

First let's look at how to access the HttpSession in a service:

Setting or getting a session value is pretty easy. First get the HttpSession then use setAttribute or getAttribute. The service is run in a servlet. The servlet's doPost function saves the HttpServletRequest in a thread local variable, this makes it accessible as the service context, ServletContext.getHttpServletRequest().

Here's some sample example service function that returns the HttpSession which is used by the put/get functions:

    function getSession()returns(HttpSession?)
        session HttpSession?;
        request javax.servlet.http.HttpServletRequest? = ServletContext.getHttpServletRequest();
        if(request != null)
            session = request.getSession();
        end
        if(session == null)
            exp InvocationException;
            exp.message = "there is no session";
            throw exp;
        end
        return(session);
    end

    function putSessionValue(key string in, value Object in)
        session HttpSession? = getSession();
        session.setAttribute(key, value);
    end
    function getSessionValue(key string in)returns(Object)
        session HttpSession? = getSession();
        return(session.getAttribute(key));
    end

 

Now for a look at the client side:

With dedicated service invocations the session is managed by the browser, with REST service invocations the Rich UI application must manage the sessions.

Using a dedicated service invocation:

If you are accessing the service in a dedicated fashion (your using clause has an HttpProxy), using the same session is easy because the session is managed by the browser that the application is running in. All services invoked in a dedicated fashion are running on the same EGL Rich UI proxy; so session sharing just happens.

Using a REST service invocation:

If you want to access the session in a REST service, it's a bit more complicated because the Rich UI application must manage the session used for the service invocations. I've tried to make it a little easier by encapsulating much of the functionality to work with the session into the CookieSession library. There's information below on where to find this library.

Here are the points you need to design your application to manage the service sessions.

When a Rich UI application makes a REST service invocation the using clause is HTTPRest. The browser still does an HTTPRequest to the EGL Proxy like it did for the dedicated invocation, but it passes information to tell the the EGL Proxy to create a new HTTPRequest to the service.

Sounds complicated but it's a few simple implementation concepts: the service invocation 'returning to' function looks for and extracts a set-cookie:JSESSIONID from the response header, if it is found the JSESSIONID is copied to the request header Cookie value on the variable used for the service invocation.

For each service invocation that wants to use the same session, you must use the same 'using' clause variable, in this case I'm using httpSession1. So each call statement that has using httpSession1 will use the same session. Since we are storing data on the variable it can't be defined in a function, it must be defined in a more global location like a handler or library. If you had four services, two on server A and two on server B you would have two HttpRest variables - one for each server. If all four services are on the same server one variable will do.

    function invokeService()
 
      call GETREC.getCustomers() using httpSession1 returning to handleCustomersResponse onException handleException;
    end   

The 'returning to' function calls processResponseHeadersSession passing the response and the 'using' clause variable.
    function handleCustomersResponse(retResult CUST[] in, http IHttp)
        //process the response headers to handle the Session ID
        CookieSession.processResponseHeadersSession(http.getResponse(), httpSession1);

        .....

In the CookieSession library processResponseHeadersSession in the CookieSession library calls extractJSessionId to extracts the set-cookie from the header, if it's found setRequestSessionId puts the JSESSIONID cookie in the request headers of httpSession1. Once the request headers contain the cookie, the same session will be used with each invocation. Each service response should check for a set-cookie meaning there has been a change in session.

    function processResponseHeadersSession(http Response in, httpVar IHttp in)
            // This function gets the jsessionid and puts the key's value in the http.request
            //by putting the key in the http.request each service invocation using that request will use the same session
            //IMPORTANT NOTE:
            //be very careful with http variables and multiple service invocations
            //service can only use the same request if the services are deployed to the same server cluster
            jsessionId string? = extractJSessionId(http);
            if(jsessionId != null)
               setRequestSessionId(jsessionId, httpVar);
            end
    end   



The code above is part of an IBMi persistent program example. You can load it from dev.eclipse.org//cvsroot/tools org.eclipse.edt/ibmi/org.eclipse.edt.ibmi.examples.

In closing

You've made it through the concepts and examples and now you want to try this. Well there a small problem in the 0.8.0 release which prevents the set-cookie from working in the development environment. You will need to either deploy the application or get a 0.8.1 build.

I hope you'll look for my next blog where I'll use the concepts above to create persistent IBMi jobs.

-Joe