Tuesday, July 31, 2012

Skinning in JSF


Why Skinning?

CSS is the tool for webdevelopers (or more likely designers) to customize sites without having to alter code. This allows for visual variability without the need to compile/test/deploy/... things. It also allows user-specific theming where the user can decide which theme looks best.
However there is one thing notably lacking in css: variables. They may be introduced in CSS3 but it will be a ways before they are actually picked up by all major browsers. Until then we can look at other frameworks to see how they achieve skinning in JSF, most notably Richfaces. This document is written using richfaces as a guideline but does not actually require any richfaces components to be present so it can be used with any JSF framework.

Richfaces skinning

Richfaces supports skinning by using a simple properties file to represent the variables. The properties file must:
  • be located in META-INF/skins
  • have the extension "skin.properties"
For example you might create a skin "META-INF/skins/test.skin.properties". To tell richfaces to use this skin, you have to configure a context parameter in the web.xml file:
<context-param>
      <param-name>org.richfaces.skin</param-name>
      <param-value>test</param-value>
</context-param>
You can take an existing skin file to see which variables exist or you can browse the component pages to see which variables they reference. Additionally richfaces will by default (you can turn this off) style regular jsf components as well in order to create a single theme for the entire application.

Using the variables yourself

Of course you don't only want to skin existing richfaces components, you may want to use the variables in the css of your own components/pages. In order to do this, you need to create a file with an extension ".ecss" instead of ".css". This will be automatically picked up by richfaces and the variables inside it will be replaced with the properties available in the skin file. Each variable must be written like this:
'#{richSkin.myParam}'
The quotes are mandatory. There are however a number of caveats.

Library lookups are wonky

Richfaces will translate your ecss outputStylesheet to something like this:
<link type = "text/css" rel = "stylesheet"
      href = "/app/rfRes/myStyleSheet.ecss.xhtml?db=eAHb-CCOEQAGJQHx" />
Which is fine unless you add the style sheet to a library, then it will generate this (note the escaped ampersand):
<link type = "text/css" rel = "stylesheet"
      href = "/app/rfRes/myStyleSheet.ecss.xhtml?db=eAHb-CCOEQAGJQHx&amp;ln=style" />
I'm not entirely sure if the problem lies with richfaces (I don't really see an obvious bug in the code with regards to URI encoding) or with jsf in general but either way it is a bit off. This may work depending on the browser, not sure how well supported this is though. Anyway, you can easily sidestep this by not putting it in a resource library and simply adding stuff on the root.

Eclipse does not like ecss files

Eclipse does not always like the variable format ecss uses. Depending on your level of bad luck you either get badly highlighted css or continuous parsing errors resulting in error popups.

Custom css properties are dropped

It is a long standing tradition to introduce new css features in browsers with a prefix for said browsers. For example take this bit of css which includes a chrome/firefox gradient and a firefox/general box-sizing declaration:
.menu .main a {
      background: -webkit-gradient(linear, left top, left bottom, from('#{richSkin.menuGradientLight}'), to('#{richSkin.menuGradientDark}'));
      background: -moz-linear-gradient(top, '#{richSkin.menuGradientLight}', '#{richSkin.menuGradientDark}');
      padding: 0px 10px;
      padding-top: 8px;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
}
When I browsed the resulting compiled ecss, I got this:
*.menu *.main a {
      background: webkit-gradient(linear,lefttop,leftbottom,from(rgb(64,64,64)),to(rgb(43,43,43)));
      background: webkit-gradient(linear,lefttop,leftbottom,from(rgb(64,64,64)),to(rgb(43,43,43)));
      padding: 0px 10px;
      padding-top: 8px;
}
As you can see, it dropped the mozilla gradient and both the mozilla and default box-sizing properties. This is likely because richfaces actually interprets the css instead of merely replacing the variables. The colors were also defined as hexadecimal and converted to their rgb equivalent. Apart from validation, I'm not entirely sure why richfaces bothers parsing the css.

Custom variable styling

To work around the issues mentioned above, I wrote my own stylesheet compiler. It requires a few things to function:
  • stylesheets must use the extension ".compiled.css" instead of ".css", so for example "mystyle.compiled.css" will be picked up by the stylesheet compiler
  • it currently uses the richfaces web.xml property mentioned above to determine which skin file you want and also scans for the "META-INF/skins/<name>.skin.properties" file, in that respect it is compatible with richfaces
The variable format is slightly more lightweight, it uses "$", the css fragment in the above would become:
.menu .main a {
      background: -webkit-gradient(linear, left top, left bottom, from($menuGradientLight), to($menuGradientDark));
      background: -moz-linear-gradient(top, $menuGradientLight, $menuGradientDark);
      padding: 0px 10px;
      padding-top: 8px;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
}
The compiler does not actually parse the stylesheet, it simply replaces all the variables it finds in the skin properties file.

Bits and pieces

The stylesheet compiler is a standalone jar file which can be plugged into any war file. It contains the following things.

CSSResourceHandler.java

First off you need to provide a custom implementation of the jsf resource handler. Based on this tutorial and the richfaces implementation it looks like this:
public class CSSResourceHandler extends javax.faces.application.ResourceHandlerWrapper {
      private Logger logger = LoggerFactory.getLogger(getClass());
      
      private Properties skinProperties;
      
      private ResourceHandler wrapped;
      
      public CSSResourceHandler(ResourceHandler wrapped) {
            logger.debug("Creating custom resource handler with parent {}", wrapped);
            this.wrapped = wrapped;
      }
      
      @Override
      public ResourceHandler getWrapped() {
            return wrapped;
      }
      @Override
      public Resource createResource(String resourceName, String library, String contentType) {
            logger.trace("createResource(" + resourceName + ", " + library + ", " + contentType + ")");
            // get the resource in the conventional way
            Resource resource = super.createResource(resourceName, library, contentType);
            // if the resource is a ".compiled.css" file, compile it
            if (resourceName.endsWith(".compiled.css"))
                  return new CompiledCSS(resource, getSkinProperties());
            else
                  return resource;
      }
      @Override
      public Resource createResource(String resourceName, String library) {
            return createResource(resourceName, library, null);
      }
      @Override
      public Resource createResource(String resourceName) {
            return createResource(resourceName, null, null);
      }
      
      @Override
public String getRendererTypeForResourceName(String resourceName) {
            if (resourceName.endsWith(".compiled.css"))
                  return "javax.faces.resource.Stylesheet";
            else
                  return super.getRendererTypeForResourceName(resourceName);
      }
      
      private Properties getSkinProperties() {
            if (skinProperties == null) {
                  // we need to figure out which skin is configured
                  FacesContext context = FacesContext.getCurrentInstance();
                  // get the richfaces skin parameter
                  String skin = context.getExternalContext().getInitParameter("org.richfaces.skin");
                  // the default skin
                  if (skin == null)
                        skin = "DEFAULT";
                  // in richfaces, the context class loader is used, not the faces context method of resource discovery
                  // note that the path must follow the below convention as per richfaces documentation & implementation
                  InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/skins/" + skin + ".skin.properties");
                  if (input != null) {
                        logger.debug("Loading skin " + skin);
                        skinProperties = new Properties();
                        try {
                              try {
                                    skinProperties.load(input);
                              }
                              finally {
                                    input.close();
                              }
                        }
                        catch (IOException e) {
                              throw new RuntimeException(e);
                        }
                  }
                  else
                        logger.error("Could not find skin " + skin);
            }
            return skinProperties;
      }
}
As you can see, it simply delegates most resource calls to the wrapper that it was initiated with. Only when the extension ".compiled.css" is found does it kick in. If the web.xml context parameter is not set, it will fall back to the richfaces default.

CompiledCSS.java

The compiled css class extends resource and much like the handler, delegates nearly all calls. It intercepts the request for content though and performs a replace on the original content before sending it back:
public class CompiledCSS extends Resource {
      private Resource original;
      private String cached;
      
      private Properties skinProperties;
      
      public CompiledCSS(Resource original, Properties skinProperties) {
            this.original = original;
            this.skinProperties = skinProperties;
      }
      
      /**
       * This is where we actually convert the css
       */
      @Override
      public InputStream getInputStream() throws IOException {
            if (cached == null) {
                  // copy to string
                  ByteArrayOutputStream output = new ByteArrayOutputStream();
                  byte [] buffer = new byte[102400];
                  int read;
                  InputStream source = original.getInputStream();
                  try {
                        while ((read = source.read(buffer)) != -1)
                              output.write(buffer, 0, read);
                  }
                  finally {
                        source.close();
                  }
                  cached = new String(output.toByteArray());
                  for (Object key : skinProperties.keySet())
                        cached = cached.replaceAll("\\$" + key.toString(), skinProperties.get(key).toString());
            }
            return new ByteArrayInputStream(cached.getBytes());
      }
      
      @Override
      public String getRequestPath() {
            return original.getRequestPath();
      }
      @Override
      public Map<String, String> getResponseHeaders() {
            return original.getResponseHeaders();
      }
      @Override
      public URL getURL() {
            return original.getURL();
      }
      @Override
      public boolean userAgentNeedsUpdate(FacesContext context) {
            return original.userAgentNeedsUpdate(context);
      }
      @Override
      public String getContentType() {
            return "text/css";
      }
}

META-INF/faces-config.xml

You need to tell JSF to use your custom resource handler, you can do this in the faces-config file:
<faces-config
xmlns = "http://java.sun.com/xml/ns/javaee"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version = "2.0">
      <application>
            <resource-handler>com.example.web.common.CSSResourceHandler</resource-handler>
      </application>
</faces-config>
At this point I'm not entirely sure how this works. Apart from the mandatory faces-config.xml file in your main war, you can apparantly have faces-config.xml files in your libraries as well. Richfaces registers its own resource handler and since both frameworks still work, JSF must register both instead of having a "the last setting wins" policy. How this plays out at runtime (are all the handlers stacked in order of appearance? Is it a flat list of handlers that is looped through?...) is unclear at this point.

Putting it together

Suppose you have a separate jar which defines some templates/components and most notably: some styling. The jar layout is as follows:
  • META-INF: everything must be in meta-inf for jsf to pick it up
    • resources: all jsf-related resources including templates must be available in the resources folder
      • style: the library "style"
        • default.compiled.css
      • templates
        • layout.xhtml
    • skins
      • custom.skin.properties
Suppose we define a very simple layout.xhtml:
<html xmlns = "http://www.w3.org/1999/xhtml"
      xmlns:h = "http://java.sun.com/jsf/html"
      xmlns:f = "http://java.sun.com/jsf/core"
      xmlns:rich = "http://richfaces.org/rich"
      xmlns:a4j = "http://richfaces.org/a4j"
      xmlns:ui = "http://java.sun.com/jsf/facelets">
      <h:head>
            <title>
                  <ui:insert name = "title"/>
            </title>
            <h:outputStylesheet name = "default.compiled.css" library = "style"/>
      </h:head>
      <h:body><ui:insert name = "main"/></h:body>
</html>
As you can see, we can reference the compiled stylesheet as we would a normal stylesheet. Now suppose we have this bit in the stylesheet:
.menu .main a {
      background: -webkit-gradient(linear, left top, left bottom, from($menuGradientLight), to($menuGradientDark));
      background: -moz-linear-gradient(top, $menuGradientLight, $menuGradientDark);
      padding: 0px 10px;
      padding-top: 8px;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
}
Then we need to add the properties to the custom.skin.properties file:
menuBorderColor=#666666
menuGradientLight=#404040
menuGradientDark=#2b2b2b
When you open the css as it is retrieved by the browser, you will see:
.menu .main a {
      background: -webkit-gradient(linear, left top, left bottom, from(#404040), to(#2b2b2b));
      background: -moz-linear-gradient(top, #404040, #2b2b2b);
      padding: 0px 10px;
      padding-top: 8px;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
}
If you package this as a "theme" library for your jsf applications, you can create an index.xhtml in your main war file that contains:
<ui:composition xmlns = "http://www.w3.org/1999/xhtml"
      xmlns:h = "http://java.sun.com/jsf/html"
      xmlns:f = "http://java.sun.com/jsf/core"
      xmlns:rich = "http://richfaces.org/rich"
      xmlns:a4j = "http://richfaces.org/a4j"
      xmlns:ui = "http://java.sun.com/jsf/facelets"
      template = "templates/layout.xhtml">
      <ui:define name = "main">
            <p>the main content comes here!</p>
      </ui:define>
</ui:composition>

Author: Alexander Verbruggen

Tuesday, July 24, 2012

Resending Idocs Not Using Transaction WE19

Problem:

When testing an interface in SAP PI I wanted to resend some idoc's to PI. Resending a succesfully processed idoc in SAP PI is not possible from SXMB_MONI.


You can use transaction WE19 from your backend system to do this, but I was not authorized to use this transaction. So I had to look for an other way to do this instead of always disturbing other colleagues who had the authorization to use transaction WE19.

Solution:

1. Use the transaction code SE38 in your SAP backend system and enter RC1_IDOC_SET_STATUS. Click on Display.




2. Click Direct Processing or press F8.

3. Enter the following fields in the Report for Converting IDoc Status:
   A.     Enter the IDoc Number in the field or click the button to the right to enter multiple IDocs.
   B.     Enter the current Status of the IDoc under Status. Looking up the status can be done using transaction code WE05.  
   C.     Now enter New Status as 30 meaning the IDoc ready for dispatch
   D.     Uncheck Test.
   E.     Click Execute.


4. Use the transaction code /nSE38 to go back to SE38. Now enter RSEOUT00. Click Display.

5. Click Direct Processing or F8.

6. Enter fields for Process All Selected IDocs.
   A.     Enter the IDoc Number in the field or click the button to the right to enter multiple IDocs.
   B.     Optional: If you want to send the IDoc to a different port then originally specified, update the field Port of Receiver with that port information.
   C.     Click Execute.


7. Check the result in SXMB_MONI.


Author: Vaast L.

Wednesday, July 18, 2012

Prince2 and integration projects

A couple of weeks ago I attended to the Prince2 practitioner course. Main driver to attend this training was to find out how it could help me in managing several simultanous B2B & EAI projects (called integration projects from here on). I want to share some reflections on what I learned and experienced in real life.

What is Prince2 (in short)?
Prince2 is a structured project management approach that was designed by the British government. It can be applied to any type of project and is not only focussed on IT-projects. Prince2 is based around 7 themes, 7 processes and 7 principles and is often seen as the approach of common sense. Because every project manager has its own idea of common sense and its own approaches to project management a lot of time is wasted in reinventing the wheel over and over. Having projects managed by external project managers is also not convenient if no common known approach is used.

For more background information on Prince2:
Official site:http://www.prince-officialsite.com/
Dutch user group: http://www.bpug.nl/prince2.html

First reflection:
The integration (EAI or B2B) requirements are often a part of a larger IT- or business project.
It is unusuall that the integration requirements are defined as a stand alone project.
That's why integration projects managers (who manage the different requests for integration solutions coming from different other projects) often have to cope with several simultanous integration projects.
Can Prince2 help in this case?
It would be great if the overal project is managed using Prince2, but if not it would mean a lot of overhead to apply Prince2 for only to the integration projects.
You could however reuse some techniques from Prince2.
For example: the Product Breakdown Structure technique of Prince2 is a vary handy visual technique for breaking down requirements and defining dependencies.
This can help a lot in visualising the scope of your integration project, especially when you have a lot of them in parallel.

Second reflection:
Knowing the above, is it usefull for integration project managers to learn Prince2?
Yes, having a good knowledge of the different themes, processes and principles that are used in Prince2 would allow you to estimate how well the projects you're integration team is working for are managed.
This knowledge allows you to foresee problems or risks in your own planning.
For example if you're being asked to implement integration requirements for a project that has no quality management strategy at all it is likely that you'll have to free some resources for the post-go live bugfixing.
If another project has no clear defined products (Prince2 word for requirements), you can foresee timing issues, changing scope and a prosponed go-live.

Third reflection:
Prince2 doens't tell me how to manage multiple (sub-)projects at the time.
It is really focussed how to manage a single project.
To address this it seems to me that it is more usefull to learn how to work with good management tools (e.g. MS Project, Issue and task tracking tools, etc).

Author: Laurenz

Saturday, July 14, 2012

WS-Security mustUnderstand in webmethods

WS-Security mustUnderstand

Environment: webmethods 8.0.1

Problem

A client has asked us to enable ws-security when using a particular webservice he exposes (webmethods policy "Consumer policy for Username"). However when we call his webservice with the appropriate message level authentication, we receive the following soap fault:

Unprocessed 'mustUnderstand' header element: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security

Analyzing the problem

Using wireshark/fiddler/.. you can inspect the soap that webmethods sends along and you see this:

...
<wsse:Security xmlns:wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:mustUnderstand="1"
      xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <wsse:UsernameToken wsu:Id = "UsernameToken-123456">
            <wsse:Username>user</wsse:Username>
            <wsse:Password Type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pass</wsse:Password>
      </wsse:UsernameToken>
</wsse:Security>
...

As you can see, the "mustUnderstand" header is indeed set. Transmitting the entire soap sans mustUnderstand via soapUI works. A quick google showed us that we are not the only ones experiencing this but no solutions were forthcoming. A succinct explanation of mustUnderstand can be found here.

The most likely cause of the issue is a bug in the client webservice implementation where he does interpret the security header but does not clear the mustUnderstand attribute which would result in the error we are seeing.

Solution

The simplest solution is of course for us not to send along the attribute but unfortunately we found no reference in the documentation regarding this particular functionality. Instead we opted to write a custom soap handler which strips the attribute when found. The webservice functionality has been subjected to a large overhaul in 8.0.1 so instead of extending javax.xml.rpc.handler.GenericHandler to add some functionality, you can work with actual services. This makes it much easier to test changes on the fly.

We create a handler service that implements the spec pub.soap.handler:handlerSpec:

The java service DgCommon.admin.utils:removeMustUnderstand uses the public org.w3c.dom api to strip the mustUnderstand:

IDataCursor cursor = pipeline.getCursor();
org.w3c.dom.Element element = (org.w3c.dom.Element) IDataUtil.get(cursor, "header");
element.removeAttribute("mustUnderstand");
IDataUtil.put(cursor, "header", element);
cursor.destroy();

This will however not work and give you a rather vague error:

com.wm.dom.DOMExceptionImpl: [ISC.133.8] Bundle:com.wm.dom.resources.DOMMessageBundle Key:133.8
      at com.wm.lang.xml.ElementNode.removeAttribute(ElementNode.java:606)
...

The exception is not entirely according to the spec so I assume this is an error in the webmethods implementation. Anyway, removing it with a fully qualified namespace does work:

element.removeAttributeNS("http://schemas.xmlsoap.org/soap/envelope/", "mustUnderstand");

You can register the handler using pub.soap.handler:registerWmConsumer (note that this must be re-registered on reboot, so do it in a startup service).

The last step is to actually add it to your list of handlers:

Author: Alexander Verbruggen

Sunday, June 24, 2012

Changing variables during runtime (BizTalk 2010)

For one of our customers I had to come up with a solution for the changing variables and different environment parameters.
For the changing send/receive location we use Deployment Framework for BizTalk, but there are some parameters that cannot be changed during runtime.

One of the proposals was too place the environment variables in the different config-files used by BizTalk. Yes BizTalk uses different config-files, we all know the config-files for 32-bit and 64-bit host instances. But not everyone knows that de isolated hosts and WCF use different ones.
This means that you have to maintain at least four files per server and we all know how quickly people forget things. This and the fact that altering config-files isn’t a best practice, we opted for the use of a database. The data can be changed at runtime and we can make an identical database with different data per environment that all the servers for that environment can access.

The following screenshot describes the table I’m using for this explanation. 

 

By including the application name as a column, we can reuse the same table, stored procedures and the generated schemas by the WCF-SQL adapter. This also eliminates the possibility of identical parameter names by different applications.  Depending on the expected records, you can index the table. We put an index on the ApplicationName together with ParameterName.
For retrieving the data, we're using the WCF-SQL adapter that calls one of two stored procedures. There are 2 stored procedures:
1. usp_GetParameterValueByName: it takes the application and parameter name as an input value and returns the value of that parameter

USE [EbtsServices]
GO
SET
ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_GetParameterValueByName]
      @applicationName nvarchar(10),
      @parameterName nvarchar(10)
AS
BEGIN     
      SET NOCOUNT ON;
      SELECT ParameterValue
      FROM ApplicationParameters
      WHERE ApplicationName = @applicationName
      AND ParameterName = @parameterName;
END

     2. usp_GetParametersByApplicationName: it takes the application name as an input value and returns all the parameters associated with the application

USE [EbtsServices]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_GetParametersByApplicationName]
      @applicationName nvarchar(10)
AS
BEGIN
      SET NOCOUNT ON;
      SELECT ParameterName , ParameterValue
      FROM ApplicationParameters
      WHERE ApplicationName = @applicationName;
END

Don’t forget to grant the correct BizTalk groups execute (with grant) permissions on the stored procedures.  Using WCF-SQL to generate the schemas results in the following three schemas: 
- dbo.xsd  
The first thing to do is to promote the ApplicationName en ParameterName element in the dbo.xsd so that we can alter them inside an orchestration.
This is a response message when using usp_GetParametersByApplication : 
 
 
As you can see, the response consists out of - depending on the number of parameters in the table - multiple StoredProcedureResultSet0 records, which have a ParameterName and ParameterValue element.  
Because BizTalk doesn’t let you promote elements that can occur multiple times, we had to use XPath expression to extract the value.

On the internet there are a lot of blogs that suggest that you count the number of repeated records and then loop x time to extract the parameter value by using the index in the XPath.  This approach has some disadvantages:
               -  you need to add three extra shapes to you orchestration (one expression to determine the count, one loop and one expression insight the loop the extract the values)
               -  It has an impact on performance because it needs to loop over all the StoredProcedureResultSet0, check if the parameter name is the one you expect and then extract the value, even if you don’t use them all.

So I searched for another solution. Just like with an collection it is possible to replace the index by a key value, in this case the parameter name. First I tried to figure out the correct xpath by trail and error. Eventually I went looking for an interesting tool. The lucky winner is Altova’s xml spy. 
I opened the response message and started to experiment until I found the correct xpath expression:
string(/*[local-name()='usp_GetAllParametersByApplicationNameResponse' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo']/*[local-name()='StoredProcedureResultSet0' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo']/*[local-name()='StoredProcedureResultSet0' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/usp_GetAllParametersByApplicationName'] /*[local-name()='ParameterName' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/usp_GetAllParametersByApplicationName' and .=’{ParameterName}’] /../*[local-name()='ParameterValue' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/usp_GetAllParametersByApplicationName'])"))

Now I just replace {ParameterName} with the parameter name (as written in the database) where I want to get the corresponding parameter value form. And then I had to place the expression inside string(), to get the value as a System.String object.
Still this wasn’t good enough for BizTalk, I got an object of type Microsoft.XLANGs.Core.Part+ArrayBasedXmlNodeList, not exactly what I needed. The solution is to use System.Convert.ToString.
The full command to retrieve the parameter value in an orchestration,  parameterValue is of type System.String. 
parameterValue = System.Convert.ToString(xpath(parametersResponse.Body , "string(/*[local-name()='usp_GetAllParametersByApplicationNameResponse' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo']/*[local-name()='StoredProcedureResultSet0' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo']/*[local-name()='StoredProcedureResultSet0' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/usp_GetAllParametersByApplicationName'] /*[local-name()='ParameterName' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/usp_GetAllParametersByApplicationName' and .= ’{ParameterName}’] /../*[local-name()='ParameterValue' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/usp_GetAllParametersByApplicationName'])"));

When using usp_GetParameterValueByName the xpath expression is slightly different:
 /*[local-name()='usp_GetParameterValueByNameResponse' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo']/*[local-name()='StoredProcedureResultSet0' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo']/*[local-name()='StoredProcedureResultSet0' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/sp_GetParameterValueByName']/*[local-name()='ParameterValue'])"))

It is still necessary to put the expression inside of string() and do a conversion to System.String.



author: Martijn

Tuesday, June 19, 2012

Common error when connecting to IBM Websphere MQ from ASP.NET


Problem

When connecting to an IBM WebSphere MQ queue using the WebSPhere MQ classes for .NET from within an ASP.NET application, you might run into the following error:

General Exception: The type initializer for 'IBM.WMQ.MQQueueManager' threw an exception.


When investigating the error a bit further we find the following error in the Windows EventViewer:

An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/1/ROOT/HealthCheckMQSeriesService
Process ID: 4972
Exception: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
StackTrace:    at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
   at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
   at IBM.WMQ.CommonServices.CreateCommonServices()
   at IBM.WMQ.CommonServices.TraceEntry(String objectId, UInt32 component, UInt32 method, Object[] parameters)
   at IBM.WMQ.MQQueueManager.Dispose(Boolean disposing)
   at IBM.WMQ.MQQueueManager.Finalize()
InnerException: System.DllNotFoundException
Message: Unable to load DLL 'amqxcs2.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
StackTrace:    at IBM.WMQ.MQCommonServices.xcsInitialize(UInt16 scope, UInt16 attributes, Byte[] charName, Byte[] charPrefix, xcsHPOOL& hPool)
   at IBM.WMQ.MQCommonServices.Initialize()




Solution

The solution is very simple.
In IIS go to the advanced settings of  application pool your application is running under.
Be sure that the “Load User Profile” property is set to true.


Run your application again and you should notice that the error disappeared.

Author: Christophe Verschuere