Thursday, December 29, 2011

ADF Faces on Weblogic 12c

Weblogic 12c is released a few weeks ago and now we have a robust, scalable Java EE6 implementation. The ADF seems to be slightly behind because a certified version of ADF Runtime is not yet available for weblogic 12c. You could try to install an older ADF runtime on 12c and I for sure ran into problems.

All I needed out of the ADF Runtime was the ADF Faces technology, so I thought to create a deployment-library of only needed jars that won't break ADF in general and then reference them from my webapp. That way, I could explore CDI and other cool features of Java EE6 bundled in Weblogic 12c, while continuing to use the ADF(faces). Now whenever the ADF Runtime is available, I can simply remove this custom ADF deployment-library from weblogic and update the needed library references in my webapp.

Here is what I did to create this temporal ADF deployment-library:

1. Created a maven web-archive project
$ mvn archetype:generate -DgroupId=com.test.adflib  -DartifactId=My-ADFLib -DarchetypeArtifactId=maven-archetype-webapp

2. Added <proj>/src/main/resources/META-INF/MANIFEST.MF to specify deployment-library name, version etc.
Specification-Title: TEMP-ADF Faces Library
Specification-Version: 1.0
Implementation-Title: TEMP-ADF Faces Library
Implementation-Version: 1.0
Implementation-Vendor: Self
Extension-Name: adf

2. Added following dependencies in the pom.xml and in added needed jars in my local repository.
    <dependency>
      <groupId>oracle.jdeveloper.library</groupId>
      <artifactId>ADF-Faces-Runtime-11</artifactId>
      <version>11.1.2.1.0</version>
      <type>pom</type>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>oracle.jdeveloper.library</groupId>
      <artifactId>ADF-Common-Runtime</artifactId>
      <version>11.1.2.1.0</version>
      <type>pom</type>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>oracle.jdeveloper.library</groupId>
      <artifactId>ADF-DVT-Faces-Runtime</artifactId>
      <version>11.1.2.1.0</version>
      <type>pom</type>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>oracle.jdeveloper.library</groupId>
      <artifactId>ADF-DVT-Faces-Databinding-Runtime</artifactId>
      <version>11.1.2.1.0</version>
      <type>pom</type>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>oracle.jdeveloper.library</groupId>
      <artifactId>ADF-DVT-Faces-Databinding-MDS-Runtime</artifactId>
      <version>11.1.2.1.0</version>
      <type>pom</type>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>oracle.jdeveloper.library</groupId>
      <artifactId>Oracle-JEWT</artifactId>
      <version>11.1.2.1.0</version>
      <type>pom</type>
      <scope>compile</scope>
    </dependency>


4. Updated the pom.xml create-war plugin to include the custom MANIFEST.MF

  <build>
     <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <configuration>
          <archive>
            <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
          </archive>
        </configuration>
      </plugin>
    </plugins>
  </build>


5. Build(mvn clean install) and deploy the artifact as a deployment-library.

6. References this custom adf library by adding following to the weblogic.xml

    <library-ref>
        <library-name>adf</library-name>
        <specification-version>1.0</specification-version>
    </library-ref>

7. The web.xml in the webapp should register all the needed servlets(FacesServlet, ResourceServlet, GraphServlet,MapProxyServlet) as needed for ADF.



Thursday, September 29, 2011

ThreadLocal

"You need to change method-signature and pass a variable from method-A to method-B to method-C and then print it. Who wants to change those many classes on a short-notice? And still there is a possibility of intermingled output with multiple-threads," a friend uttered in exasperation. We thought to explore a way of implementing what he needed(pass a new parameter) without actually changing the method-signatures, thereby not affecting other code. And also, see if we could somehow make that passed value thread-safe.

ThreadLocal came to mind. The concept of ThreadLocal is a bit elusive so I decided to put-together this blog-post with a simplest and shortest possible example. In simplest terms, ThreadLocals could be used to associate a state to a thread-of-execution, where the normal variables can not work. And we could use that thread-state to attach the parameter we want to pass, and down the thread-of-execution it could be retrieved by other code. Problem solved:  no method-signature changes, and thread-safe.

Here from javadoc about the class java.lang.ThreadLocal<T>:

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).


To keep the example simple, we will start only two named threads, and will attempt to retain thread-name in a variable as a state during a thread-of-execution. And to compare/contrast our attempts, we will store the thread-name in a ThreadLocal variable, and also in a normal variable.

Here is the execution output of the above code:

Fred#State1=>Fred#State2=>Fred
Lucy#State1=>Lucy#State2=>Lucy
Fred#State1=>Lucy#State2=>Fred
Lucy#State1=>Lucy#State2=>Lucy
Fred#State1=>Lucy#State2=>Fred
Lucy#State1=>Lucy#State2=>Lucy
Fred#State1=>Lucy#State2=>Fred

As you could see, the State1, retained in a normal variable was overwritten by the last thread as it entered the Running state. It could even have been "Fred", if that thread was to enter the Running state towards the end. So clearly, using a normal variable as above to retain state in a thread-of-execution doesn't work. Now contrast that too State2 and see how each thread-of-execution correctly prints the assigned state.

So next time when you are debugging a piece of code with multiple-threads, try using it. An example use-case would be in servlets as  each request creates a new thread-of-execution, and the servlet in-turn calls business-methods. You may be able to add request-specific, thread-specific data in the servlet and be able to access it deep-down in other methods where access to HttpSession or other shared-objects may not be possible.


Tuesday, May 17, 2011

Adding Weblogic security-policies using WLST

I struggled today to add a simple url-pattern security-policy on Weblogic using WLST(Web-Logic-Scripting-Tool). A google-search not revealing much is a rarity these days, so I decided to research and blog my findings here. I hope it help others, and it sure will help me as I am going to forget about it in a couple months, especially with a long vacation around the corner.

The problem I was trying to solve is simple: I wanted to enforce HTTP Basic authentication on an URI, using a url-pattern security-policy, and be able to configure this security using WLST. Ultimately, an example URL like http://host:port/myapp/someresource/* will have a restricted access.

This is fairly easy using the Weblogic admin-console, and below are typical high-level steps. We will simplify this further by excluding roles, groups and grant access only to a single-user.

1. Deploy application with CustomRolesAndSecurity as a security-model.
2. Add a user in default security-realm
3. Add url-pattern security-policy, and then add policy-condition to allow access to only #2 user.

Simple. But now how do we do the same using WLST? The #1 and #2 steps above using WLST are well-documented elsewhere, and the jython snippet in-brief here:

Application Deployment: myapp.war
deploy('myapp','/tmp/myapp.war',securityModel='CustomRolesAndPolicies')

Adding user: UserId=>testuser, Password=>testpass12
securityRealm=cmo.getSecurityConfiguration().getDefaultRealm()
authenticationProvider=securityRealm.lookupAuthenticationProvider('DefaultAuthenticator')
authenticationProvider.createUser('testuser','testpass12','comment about user')

Now the real topic of the blog-post - how to add the security-policy using WLST? There is a weblogic MBean called XACMLAuthorizerMBeanImpl and it has two methods to create/add a security-policy for a resource.

1. createPolicy(String resourceId, String expression)
A challenge in using above method is to compose the resourceId and the expression. There are different types of resources which could be protected such as uri, ejb, jms,webservice etc, and policies for all can be created using the same method. The resourceId however has to be resource-type specific, with patterns and stuff encoded, so care need to be taken to generate an appropriate string. To that, Resource classes in weblogic.security.service package could be used.

import weblogic.security.service.URLResource
#r=weblogic.security.service.URLResource(application,context_path,pattern,httpMethod,transport)
r=weblogic.security.service.URLResource('myapp','/myapp','/somepath/*',None,None)
resourceID=r.toString()

The resourceID value we get from above is: 
type=<url>, application=myapp, contextPath=/myapp, uri=/somepath/*.

Next, we need the expression and that is bit of a challenge too, but for a simple case of only one user it is Usr(testuser) without any logical-operators or so.

expression='Usr('+'testuser'+')'

With resourceID and expression available, now simply get the authorizer MBean and call createPolicy() operation, as follows:

authorizer=securityRealm.lookupAuthorizer('XACMLAuthorizer')
authorizer.createPolicy(resourceID,expression)

2. addPolicy(String policy)
This second method of creating a policy needs access policy defined in a XACML document. Here is a jython snippet that uses a sample XACML to create a policy using addPolicy() method. I chose TQS of jython to compose the long XACML for the above URL pattern.

policy="""
    <Policy PolicyId="urn:bea:xacml:2.0:entitlement:resource:type@E@Furl@G@M@Oapplication@Emyapp@M@OcontextPath@E@Umyapp@M@Ouri@E@UTest2@U@K" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
        <Description>Usr(testuser)</Description>
        <Target>
            <Resources>
                <Resource>
                    <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">type=&lt;url&gt;, application=myapp, contextPath=/myapp, uri=/somepath/*</AttributeValue>
                        <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:resource:resource-ancestor-or-self" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
                    </ResourceMatch>
                </Resource>
            </Resources>
        </Target>
        <Rule RuleId="primary-rule" Effect="Permit">
            <Condition>
                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">
                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">testuser</AttributeValue>
                    <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"/>
                </Apply>
            </Condition>
        </Rule>
        <Rule RuleId="deny-rule" Effect="Deny"></Rule>
    </Policy>
"""
authorizer=securityRealm.lookupAuthorizer('XACMLAuthorizer')
authorizer.addPolicy(policy)

Now some questions:
1. How do I get XACML for a possibly complex policy?
One idea would be create the complex security-policy through admin-console, and then export the security-realm(security-realm-->migration-->export). It creates a bunch of files in a specified directory, and one file in there of interest is the XACMLAuthorizer.dat.

The XACMLAuthorizer.dat, despite the extension, is a valid XML document and contains the whole set of policies.  Now search for the policy that you created through the admin-console and grab that complete "Policy" element, and that is the XACML document you need using WLST/addPolicy() method.

2. With regard to createPolicy() method, I can create a resourceID using appropriate class for a resource from the weblogic.security.service package. However, how do I create a complex expression if there are multiple policy-conditions?

One approach would be to add policy-conditions through the admin-console. And then simply query the Expression attribute as follows for use in WLST. 

import weblogic.security.service.URLResource
r=weblogic.security.service.URLResource('myapp','/myapp','/someresource/*',None,None)
resourceID=r.toString()
securityRealm=cmo.getSecurityConfiguration().getDefaultRealm()
authorizer=securityRealm.lookupAuthorizer('XACMLAuthorizer')
import java.util.Properties
p=authorizer.getPolicy(resourceID)
Expression=p.get('Expression')
print Expression

Resources:
1.  Weblogic Mbean reference